如何在静态上下文中等待线程?

Posted

技术标签:

【中文标题】如何在静态上下文中等待线程?【英文标题】:How to Wait a Thread in a Static Context? 【发布时间】:2021-09-23 02:30:19 【问题描述】:

我试图在静态上下文中等待一个线程,直到它满足 Java 中的条件。

据我了解,Object.wait() 导致当前线程等待,直到另一个线程通知对象它正在等待处理。

所以我尝试在静态方法上应用相同的机制,但由于上下文是静态的,wait() 将导致当前线程等待类,notify() 将通知类本身,而不是对象.

但是,在静态上下文中,当前对象未定义。那么我怎么才能调用wait() 方法呢?

public static synchronized void waitThread() 
    //how can I call the current thread to wait in a static method?
    //wait();

【问题讨论】:

【参考方案1】:

wait() 是 Object 方法,而不是 Thread 方法。我建议你像这个例子一样使用静态锁对象:

public class ThreadTest 

Thread1 t1;
Thread2 t2;
static Object lock = new Object();

public static void main(String[] args) 
    new ThreadTest().go();


private void go() 

    t1 = new Thread1();
    t2 = new Thread2();
    t1.start();
    t2.start();


private class Thread1 extends Thread 
    @Override
    public void run() 
        ThreadTest.print("ONE");
        synchronized (lock) 
            lock.notify();
        
    


private class Thread2 extends Thread 
    @Override
    public void run() 
        try 
            Thread.sleep(300);
         catch (InterruptedException e) 
        
        synchronized (lock) 
            lock.notify();
        
        ThreadTest.print("two");
    


private static void print(String str) 
    synchronized (lock) 
        try 
            lock.wait();
         catch (InterruptedException e) 
        
    

    for (int i = 0; i < str.length(); i++) 
        System.out.print(str.charAt(i));
        try 
            Thread.sleep(300);
         catch (InterruptedException e) 
        
    



感谢 wait() 和 notify() 调用,打印输出看起来不错。没有它们,打印输出将会混淆。

另外请考虑使用 CountDownLatch,这将是一种更复杂的线程协调方法。

【讨论】:

如果没有Thread.sleep(),输出是否仍能保证相同? 该代码仅在线程 1 首先调用 print() 时才有效,因此需要第一个 sleep()(我认为这没问题,因为这只是一个展示想法的虚拟示例)。第二个 sleep() 用于确保两个线程同时调用 print(),以便可以将其删除(但是即使您没有正确处理线程,您也可以很幸运并获得正确的输出) 感谢您的回答,这在很多方面都有帮助。顺便说一句,我认为您的意思是 CountDownLatch 而不是 CuntDownLatch 哈哈

以上是关于如何在静态上下文中等待线程?的主要内容,如果未能解决你的问题,请参考以下文章

为啥不等待 Task.Run() 同步回 UI 线程/原始上下文?

如何重用线程 - pthreads c

EF 数据上下文 - 异步/等待和多线程

多线程

导致死锁的异步/等待示例

Java 并发编程 -- 并发编程线程基础(线程创建与运行线程通知与等待join / sleep / yield方法线程中断线程上下文切换死锁守护线程与用户线程ThreadLocal)