多线程Java同步块
如果我们有一个方法:
public void doSomething(){
synchronized(this){
//some code processing here
}
String temp = "init"; //instead of i++
synchronized(this){
//some other code processing here
}
}
这个方法等同于public synchronized void doSomething()
是否有任何理由认为,在某些执行中,线程调度程序将产生与同步整个函数相同的有效流?也就是说:
- Thread1进入第一个同步块李>
- Thread2块李>
- Thread1继续执行
i++
并移动到第二个同步块,而Thread2仍处于阻塞状态李> - 因此,Thread2在Thread1退出两个同步块后进入该方法李>
我只需要知道:
- 我能指望所有的执行上下文,这两个线程(Thread1和Thread2)都能同时出现在方法中吗?例如,在第一个同步块中使用Thread2,在第二个同步块中使用Thread1,以实现并发李>
- 是否会有一些执行流(一次只有一个线程)在方法中有效地序列化整个流,使其等效于
public synchronized void doSomething()
李>
# 1 楼答案
不,它不等同于
synchronized void doSomething()
,因为i++
不是原子操作。事实上,它可能有类似的作用int temp = i; i = i + 1; result = temp
如果这些操作不是原子化的,那么
i
的值可以在其处于不良状态时读取# 2 楼答案
此方法与使其成为同步方法不同。 你解释的行为可能会被看到,但永远无法得到保证
# 3 楼答案
不,不是。例如上面的代码
线程一进入第一个同步块,执行它,然后退出,然后被关闭。 线程2进入第一个同步块执行它,然后在被关闭之前进入第二个同步块。 线程一现在无法继续,直到线程二退出第二个同步块
如果整个方法是同步的,这种模式就不会发生
# 4 楼答案
在一些执行中,它将具有与同步整个函数相同的流程,这是肯定的——但为了真正等同于使方法同步,它必须具有与所有执行相同的流程
实际上,另一个线程有可能在执行的中途获取锁(无论是对于这个方法还是同一个监视器上的其他代码锁定)。如果方法本身是同步的,就不会发生这种情况,因此它们不是等价的
(顺便说一句,锁定
this
通常被认为是不好的做法;我不记得上次我写了一个同步的方法。我锁定了私人持有的监视器,因此我知道我的代码是唯一可能锁定它们的代码。)编辑:要响应您的编辑:
绝对不是!可以保证不会在同一个监视器上同步同步一个同步块中的两个线程
代码有三个部分:第一个同步块、未同步部分和第二个同步部分
一次可以在非同步部分执行任意数量的线程。对于任何一个实例(因为您正在
this
上同步),只有一个线程可以执行已同步块的或。如果想要实现并发,就必须在不同的监视器上进行同步此外,听起来您希望确保调度器在等待锁时允许另一个线程获取锁。我不相信有任何这样的保证——执行第一个块的线程可以释放锁,但在相同的时间片中继续,并在其他线程进入之前重新获取它。在一些JVM中,这可能不会发生,但我不相信有任何保证