Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java同步块——锁定对象_Java_Synchronized - Fatal编程技术网

Java同步块——锁定对象

Java同步块——锁定对象,java,synchronized,Java,Synchronized,在示例代码中 public class MsLunch { private long c1 = 0; private long c2 = 0; private Object lock1 = new Object(); private Object lock2 = new Object(); public void inc1() { synchronized(lock1) { c1++; } } public void inc2() { synchron

在示例代码中

public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();

public void inc1() {
    synchronized(lock1) {
        c1++;
    }
}

public void inc2() {
    synchronized(lock2) {
        c2++;
    }
}
}
在第页

lock1lock2分别控制c1c2上的更新

但是,

    synchronized(lock2) 
正在获取对象的锁lock1,并在同步块

    synchronized(lock1) {
        c1++;
    }
被执行

执行此块时,可能会出现以下情况: 关于这个对象的成员c1的更新仍然存在——我没有 查看此更新是如何被阻止的 在锁1上同步,如代码中所示

正是对象lock1对-- 没有别的了(?)

那么,实施情况如何

public void inc1() {
    synchronized(lock1) {
        c1++;
    }
}
在上述代码中不同于

public void synchronized inc1() {
        c1++;
}
甚至

public void inc1() {
    synchronized(c1) {
        //do something on c1
    }
}
c1是对象而不是基元时

我错过了什么

注:我看到


在其他一些讨论中

据我所知,你的说法不正确。你链接的页面也没有说明你在问题中的主张。锁就是这样工作的:锁根本不会阻止线程访问对象。锁只会阻止另一个线程在另一个线程已经获得该锁时获取同一个锁

这意味着这可能发生:

Thread A: synchronize (lockObject)
Thread B: lockObject.toString();
Thread A: release the lock on lockObject
当两个线程同时需要相同的锁时,会发生这种情况:

Thread A: synchronize (lockObject)
Thread B: synchronize (lockObject) // This will block until (1) !
Thread A: do some stuff and then release lock on lockObject
Thread B: gets the lock (1)
然而:

public void synchronized inc1() {
    c1++;
}
与以下内容完全相同:

public void inc1() {
    synchronized(this) {
        c1++;
    }
}

据我所知,你的陈述是不正确的。你链接的页面也没有说明你在问题中的主张。锁就是这样工作的:锁根本不会阻止线程访问对象。锁只会阻止另一个线程在另一个线程已经获得该锁时获取同一个锁

这意味着这可能发生:

Thread A: synchronize (lockObject)
Thread B: lockObject.toString();
Thread A: release the lock on lockObject
当两个线程同时需要相同的锁时,会发生这种情况:

Thread A: synchronize (lockObject)
Thread B: synchronize (lockObject) // This will block until (1) !
Thread A: do some stuff and then release lock on lockObject
Thread B: gets the lock (1)
然而:

public void synchronized inc1() {
    c1++;
}
与以下内容完全相同:

public void inc1() {
    synchronized(this) {
        c1++;
    }
}

在不指定锁对象的情况下标记块或方法
synchronized
,将在拥有该方法的对象上同步;在本例中,
mssunch
实例。它相当于
同步(this)
。锁定对象习惯用法的目的是打破锁定,以便可以分别操作
c1
c2
synchronized
块只能在对象上同步,而不能在原语上同步。

标记块或方法
synchronized
,而不指定锁定对象将在拥有该方法的对象上同步;在本例中,
mssunch
实例。它相当于
同步(this)
。锁定对象习惯用法的目的是打破锁定,以便可以分别操作
c1
c2
synchronized
块只能在对象上同步,而不能在基元上同步

synchronized(lock2){
  // do sth
}
实际上正在获取对象lock2的锁

何处为

public void synchronized inc1() {
        c1++;
}
获取此对象上的对象

一旦程序离开块,同步程序获取的锁将被释放

实际上正在获取对象lock2的锁

何处为

public void synchronized inc1() {
        c1++;
}
获取此对象上的对象


同步程序获取的锁将在程序离开块后释放。

实现1。

您正在锁定
lock1
对象。其他任何需要锁定的
lock1
都无法执行。将两个方法锁定在不同的对象上意味着这两个方法可以同时运行,但没有两个线程可以同时运行同一个方法

实施2.

使方法
同步
意味着整个方法体隐式地位于
同步(this)
块中(或在
对象上同步,如果方法是
静态
。如果两个方法都是
同步的
,则一个方法会阻止另一个方法同时运行,这与在不同对象上锁定两个方法不同

实施3.


如果
c1
是一个对象而不是一个原语,那么语义非常类似于实现1-锁定显式对象。

实现1。

您正在锁定
lock1
对象。没有其他需要锁定
lock1
的对象可以执行。将两个方法锁定在不同的对象上意味着这两个方法可以同时运行,但没有两个线程可以同时运行同一个方法

实施2.

使方法
同步
意味着整个方法体隐式地位于
同步(this)
块中(或在
对象上同步,如果方法是
静态
。如果两个方法都是
同步的
,则一个方法会阻止另一个方法同时运行,这与在不同对象上锁定两个方法不同

实施3.


如果
c1
是一个对象而不是一个原语,那么语义与实现1非常相似-锁定一个显式对象。

我遇到了一个线程占用锁的问题

for(;;){synchronized(lockObject){
...
}}
我猜Java不喜欢一有机会就自行解锁它

使用java.util.concurrent.locks.ReentrantLock修复了该问题

static ReentrantLock lock = new ReentrantLock();
for(;;){
  lock.lock();
  ...
  lock.unlock();
}

我有一根线卡住锁的问题

for(;;){synchronized(lockObject){
...
}}
我猜Java不喜欢一有机会就自行解锁它

使用java.util.concurrent.locks.ReentrantLock修复了该问题

static ReentrantLock lock = new ReentrantLock();
for(;;){
  lock.lock();
  ...
  lock.unlock();
}

为什么您认为
synchronized(lock2)
正在锁定
lock1
?@chrylis-read我熟悉并发文档,只是阅读了该页面。它没有说
synchronized(lock2)
锁定
lock1
,因为