我们可以将线程连接方法放在synchronized方法中

时间:2015-05-15 04:52:06

标签: java multithreading synchronized

我可以在synchronized方法中使用thread.join吗?

class Table{  
 synchronized void printTable(int n){//synchronized method  
   for(int i=1;i<=5;i++){  
     System.out.println(n*i);  
     try{  
      Thread.join(); 
     }catch(Exception e){System.out.println(e);}  
   }  
 }  
}  

我可以使用thread.join而不是wait吗?

2 个答案:

答案 0 :(得分:1)

首先:它不是静态方法,因此Thread.join不起作用。
是的,你可以打电话。没有编译或运行时异常,但请考虑以下两点可能是你不想在此之后想要这样做。 :)
加入一个线程意味着一个人等待另一个人结束,这样你就可以安全地访问它的结果,或者在两个人完成工作后继续。所有重载版本的join()都是最终的并且是同步的。
同步方法支持一种简单的策略来防止线程干扰和内存一致性错误:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的。

答案 1 :(得分:1)

目前还不清楚你在这里尝试做什么。看起来您可能误解了synchronized关键字的作用以及示例中使用的锁的位置。

Thread.join();无效,因为它是一种实例方法。你真正想加入什么线程并不明显。您需要提供对您想要等待终止的任何线程的引用。

这里是Java tutorial description of Thread#join

  

join方法允许一个线程等待另一个线程的完成。如果t是其当前正在执行其线程的Thread对象,则

     

t.join();

     

导致当前线程暂停执行,直到t的线程终止。连接过载允许程序员指定等待期。但是,与sleep一样,join依赖于操作系统进行计时,因此您不应该假设连接将等待您指定的时间。

为什么要在for循环中执行此连接并不明显,因为join方法一直等到线程完全完成(因为不再存在),多次调用它不会似乎很有用。 (您是否需要当前线程加入多个线程?或者您希望提供超时值并反复尝试加入同一个线程?)

在你的评论中,当你问:

  

关于我可以使用thread.join而不是wait

的简单问题

你不能使用一个作为另一个的替代品。 synchronized方法保持的锁与连接使用的锁(获取,释放,然后重新获取)不同。 join方法使用线程上的锁,wait必须使用Table实例上的锁(synchronized方法使用的锁)。 从synchronized方法中调用wait将释放Table实例上的锁定(让其他线程有机会访问该实例),但调用join不会。由于synchronized方法持有锁定表的实例,这意味着你的线程拒绝任何其他线程访问该表实例,直到它加入的任何线程结束。虽然join是使用wait实现的,但它等待的是来自监视器的通知,你要加入的线程,而不是Table对象,所以Table实例上的锁永远不会被释放,直到方法完成,这取决于连接完成。持有锁时,线程处于休眠状态;如果其他线程需要访问此Table对象,那么您将拒绝使用此方法访问其他线程。

所以(假设你添加一些逻辑来提供当前线程需要加入的任何线程或线程的引用)你可以这样做,但它看起来很糟糕。线程应该最小化他们持有锁的时间。可能像CyclicBarrier这样的更高级别的构造在这里很有用(尽管在执行此操作时你仍然不应该保持锁定。)