【问题标题】:Control not returning to the waiting thread after notify通知后控制不返回等待线程
【发布时间】:2016-08-02 13:31:25
【问题描述】:

我创建了一个名为 ThreadA 的新线程并在主线程中启动它。

我在ThreadA等待一些操作完成。

经过一些操作后,我使用notify发送了通知。

但是主线程中wait下面的代码没有被调用,它等待ThreadA的整个代码完成。

是线程的本质还是只是线程访问运行问题?

Job job = new MyJob(); 
job.schedule(); 
synchronized(job) {
    job.wait(); 
    sysout("After notify");
} 

这里job 是 org.eclipse.core.runtime.jobs

内部Job运行方法:

run {
    synchronized(this) {
        step 1(); 
        notify(); 
        step 2();
    }
} 

这里的第 2 步是大代码。

【问题讨论】:

  • 请显示您的代码(您是如何调用waitnotify)。
  • 工作工作 =new MyJob();工作时间表();同步(作业){job.wait(); sysout("After notify")} 这里的工作是 org.eclipse.core.runtime.jobs。
  • 内部作业运行方法:运行{synchronized(this){step 1();通知(); step 2();}} 这里第 2 步是大代码。
  • 我的代码首先进入第 2 步,只有在完成第 2 步后才在主线程中调用 sysout
  • 我可以建议将wait()notify() 替换为更现代的东西,例如java concurrent 提供的实用程序类吗?

标签: java multithreading wait


【解决方案1】:

通知线程在释放锁之前不会真正发送通知。您需要在通知发生之前释放锁定,而您的代码没有这样做。

那么接收通知的线程当然没有锁。它必须先获取锁才能行动,如果线程正在等待,则需要获取锁才能退出等待方法。通知线程没有偏好,也没有理由认为它必须首先采取下一步行动。

这就是为什么建议始终在循环中调用 wait 的部分原因,而您没有这样做。一旦获得锁,唤醒线程应该检查它被唤醒的条件是否仍然为真。

从调用 step1 到调用 step2,您的 Job run 方法一直持有锁。对于通知线程要对通知做任何事情,它必须停止等待,这需要在退出等待方法之前重新获取锁(因为它必须进入自己的同步块)。这意味着在通知线程释放锁之前发送通知是没有意义的,因为无论如何等待线程对此无能为力。

【讨论】:

  • Synchronized(job) 是否获得该对象的锁定?
  • @user3302323 synchronize 关键字标记只能由单个线程同时进入的块。如果其他线程当前在同一对象的同步块中,则暂停执行,直到其他线程离开其同步块
  • 能否详细说明如何释放和获取对象上的锁?
  • @user3302323 请通读the documentation on instrinsic locks。希望您会了解到,一旦离开同步块(将其视为执行指针传递} 符号时)或同步块内发生未由内部try-catch块处理的异常,锁就会被释放同步块
  • 公共类 ThreadMain { public static void main(String[] args) { System.out.println("In main"); ThreadMain main=new ThreadMain(); ThreadA 可运行 =new ThreadA(main);线程线程=新线程(可运行);线程.start();同步(可运行){ 尝试 { runnable.wait(); System.out.println("线程通知"); } catch (InterruptedException exp) { exp.printStackTrace(); } } } }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多