锁和.join()方法之间的区别

时间:2019-05-12 19:08:16

标签: java multithreading

假设您有两个线程,线程1和线程2。如果您同时调用thread1.start()和thread2.start(),并且它们都打印出1到5之间的数字,那么它们都将同时运行,并且会以任意顺序随机打印出这些数字,如果我没看错。为防止这种情况,请使用.join()方法确保首先执行某个线程。如果这是.join()方法的作用,那么Lock对象的作用是什么?

2 个答案:

答案 0 :(得分:1)

Thread.join用于等待另一个线程完成。 join方法使用Thread对象上的隐式锁,并在其上等待调用。等待线程完成后,它会通知等待线程,以便可以停止等待。

Java有多种使用锁来保护对数据访问的方式。有一个隐式锁定,它使用每个Java对象中内置的锁(这是synced关键字所在的位置),然后有显式Lock对象。两者都保护数据免受并发访问,不同之处在于显式锁更灵活,功能更强大,而隐式锁旨在更易于使用。

例如,对于隐式锁,我无法在同步方法或块的末尾释放锁,JVM确保在线程离开时释放锁。但是使用隐式锁进行编程可能会受到限制。例如,没有单独的条件对象,因此,如果有不同的线程针对不同的事物访问共享对象,则不可能仅通知它们的一部分。

使用显式锁,您可以获得单独的条件对象,并且只能通知那些正在等待特定条件的线程(生产者可能正在等待一个条件,而消费者正在等待另一个条件,请参见ArrayBlockingQueue类作为示例),并且您可以实现更多涉及多种模式,例如移交锁定。但是您需要更加小心,因为额外的功能会带来复杂性,并且释放锁取决于您。

答案 1 :(得分:0)

锁定通常可以防止多个线程同时运行代码块。这是因为一次只能有一个线程可以获取锁并在其中运行代码。如果线程想要该锁但已被使用,则该线程将进入等待状态,直到释放该锁。如果您有许多线程在等待释放锁,那么下一个获得锁的线程是INDETERMINATE(无法预测)。这可能导致线程正在等待锁的“线程匮乏”,但是它永远都不会得到它,因为其他线程似乎总是会得到它。这是一个非常通用的答案,因为您没有指定语言。某些语言可能略有不同,因为它们可能有确定的方法来确定下一个锁定者。