Java 关于两个线程的同步

Java 关于两个线程的同步,java,multithreading,Java,Multithreading,假设一个单例实例被两个线程访问。两个线程正在访问名为doTask()的相同函数 如果线程B正在执行繁重的任务,当线程A访问doTask()时,我知道线程A将运行//第一个非同步的代码,然后线程A注意到锁是由线程B获取的,因此它无法运行同步的//一些繁重的任务。但是线程A是否会跳过同步的繁重任务,继续运行//最终非同步代码,或者线程A是否会等待锁,甚至不执行//最终非同步代码 (我知道我可以尝试一下,但目前我没有合适的开发环境…java中的synchronized块迫使线程等待,直到它们可以获得对

假设一个单例实例被两个线程访问。两个线程正在访问名为
doTask()
的相同函数

如果线程B正在执行繁重的任务,当线程A访问
doTask()
时,我知道线程A将运行
//第一个非同步的代码
,然后线程A注意到
锁是由线程B获取的,因此它无法运行同步的
//一些繁重的任务
。但是线程A是否会跳过同步的繁重任务,继续运行
//最终非同步代码
,或者线程A是否会等待锁,甚至不执行
//最终非同步代码


(我知道我可以尝试一下,但目前我没有合适的开发环境…

java中的
synchronized
块迫使线程等待,直到它们可以获得对象的锁为止

它将等待B完成,然后为
lock
挂上锁,并在块内运行代码,然后从另一端继续运行


需要注意的是,当B完成执行
一些繁重任务的内容时,它将释放
lock
上的锁,并“同时”运行
最终非同步代码A运行同步块。

java中的
同步块迫使线程等待,直到它们能够获得对象的锁

它将等待B完成,然后为
lock
挂上锁,并在块内运行代码,然后从另一端继续运行


需要注意的是,当B完成
一些繁重任务的内容时,它将释放
锁上的锁,并在A运行同步块的“同时”运行
最终非同步代码。

当一个线程获取同步对象的监视器时,然后剩下的线程也会尝试获取它,这个过程称为轮询。因为所有剩余线程都试图通过反复检查监视器锁定状态来获取该对象的监视器。当锁被释放时,它可以被任何线程获取。它实际上是由调度程序决定的。

当一个线程获取同步对象的监视器时,其余线程也将尝试获取它,这个过程称为轮询。因为所有剩余线程都试图通过反复检查监视器锁定状态来获取该对象的监视器。当锁被释放时,它可以被任何线程获取。它实际上是由调度程序决定的。

线程A将一直无限期地等待,直到线程B释放锁为止

在极端情况下,如果锁从未松开,螺纹A将永远卡住

有时这已经足够好了,但通常您需要更好地控制事情,这是像这样的类派上用场的时候

这可以完成
synchronized
提供的所有功能,但也可以执行诸如检查锁是否已由当前线程拥有、在不等待的情况下尝试获取锁(如果锁已被另一个线程占用,则会立即失败)或将其等待时间限制在一定时间内等操作


还请注意,虽然这些解决方案可用于控制互斥,但这不是它们的唯一功能,它们在可见性方面也起着重要作用。

线程A将始终无限期地等待,直到线程B释放锁

在极端情况下,如果锁从未松开,螺纹A将永远卡住

有时这已经足够好了,但通常您需要更好地控制事情,这是像这样的类派上用场的时候

这可以完成
synchronized
提供的所有功能,但也可以执行诸如检查锁是否已由当前线程拥有、在不等待的情况下尝试获取锁(如果锁已被另一个线程占用,则会立即失败)或将其等待时间限制在一定时间内等操作


还请注意,虽然这些解决方案可用于控制互斥,但这不是它们的唯一功能,它们在可见性方面也起着重要作用。

它将等待B完成并移除您的singleton构造函数丢失的锁。它将等待B完成并移除您的singleton构造函数丢失的锁。“同时”在这里有点误导,JVM可以在块内的
synchronized
块之前和之后自由移动位,只要它不破坏任何其他重新排序保证(例如,使用易失性读/写)。更精确的说法是,不能保证线程A将看到线程B执行的
最终非同步代码中所做的任何更改。是的,因此引号是“同时”;)“同时”在这里有点误导,JVM可以在块内的
synchronized
块之前和之后自由移动位,只要它不破坏任何其他重新排序保证(例如使用易失性读/写)。更精确的说法是,不能保证线程A将看到线程B执行的
最终非同步代码中所做的任何更改。是的,因此引号是“同时”;)
public class MySingleton {
    Object lock = new Object();
    // I omit the constructor here.

    public void doTask() {
         //first non-synchronized code

         synchronize(lock) {
             //some heavy task
         }

         //final non-synchronized code
    }
}