Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Multithreading - Fatal编程技术网

Java 同步使对象锁定

Java 同步使对象锁定,java,multithreading,Java,Multithreading,我对对象锁有点困惑。 下面的类有4个方法,方法addB()是同步的 在我的scienario中,有4个线程。当一个线程2访问addB()方法(它在测试对象上创建了一个锁)时,是否会有其他线程同时访问addC()或addD() 对象锁一次只允许一个线程吗 class Test{ private Integer a; private Integer b; private Integer c; private Integer d; pu

我对对象锁有点困惑。 下面的类有4个方法,方法addB()是同步的

在我的scienario中,有4个线程。当一个线程2访问addB()方法(它在测试对象上创建了一个锁)时,是否会有其他线程同时访问addC()或addD()

对象锁一次只允许一个线程吗

class Test{
       private Integer a;
       private Integer b;
       private Integer c;
       private Integer d;


   public void addA(){
      synchronized(a) {
         a++;
      }
   }
   public synchronized void addB(){
         b++;
      }

   public void addC(){
         c++;
      }

   public void addD(){
         d++;
      }    
   }
编辑: 我有3个线程(t1、t2和t3),每个线程都将访问addB()、addC()和addD()。如果线程t1访问addB()方法,那么线程t2可以同时访问addC()方法吗?如果不是,t2状态是什么

class Test{
       private Integer a;
       private Integer b;
       private Integer c;
       private Integer d;


   public void addA(){
      synchronized(a) {
         a++;
      }
   }
   public synchronized void addB(){
         b++;
      }

   public synchronized void addC(){
         c++;
      }

   public synchronized void addD(){
         d++;
      }    
   }

锁确实一次只允许一个线程,但不同的锁不会相互影响

在您的示例中,您有两个锁—一个锁在属于
a
的互斥锁上,另一个锁在属于
this
的互斥锁上(这在您使用
synchronized
关键字时是隐式的,正如您在文章中正确提到的)

因此,对
addB()
的调用将被同步,但不会阻止对任何其他方法的调用。如果一个线程持有
上的锁,另一个线程可以持有
a
上的锁,多个其他线程可以同时执行
addC()
addD()


Edit:另外,如果您确实在使用
Integer
s,您可能有兴趣了解
AtomicInteger
类。它们提供原子操作,因此您无需担心围绕它们进行同步。

如果代码中有两个锁,则只有一个线程能够遍历锁1或锁2。这两个锁都是独立的,这意味着它们不会相互排除线程

锁#1在对象上同步

   public void addA(){
      synchronized(a) {
         a++;
      }
   }
锁#2在测试实例上同步(此)


addC()和addD()完全没有锁,任何数量的线程都可以同时访问它们。

同步块只是一个环境,您可以将它“执行”的对象视为一个对象。实际上,只允许一个线程同时锁定一个对象

方法C和D从不锁定,可以由任何线程随时执行


正如其他人所指出的,当您执行
a++
时,您将创建Integer的一个新实例。

锁提供了一种同步线程的机制。这意味着在同一时间点,只有一个线程可以访问对象的AddB方法。
除非在代码完成后释放锁,否则下一次代码迭代无法进入块。

线程的锁定取决于所用对象的实例 e、 g:

addB()函数可以重写为

public void addB(){
  synchronized(this){
    //func
 }
}
  • 这里的锁位于对象上,用于访问函数片段。 其他线程可以访问其他函数
  • 更多关于addA的锁的内容是对象obj.a,它有自己的独立锁。因此,两个不同的线程可以同时访问addA和addB

整数是不可变的,这意味着它永远不会改变。当你做a++时,它实际上会创建一个新的对象a。因此,您的锁将变得混乱,因为当a被删除并且值被分配给新的a时,锁将丢失。这对您的问题并没有真正的帮助,但可能会修复一个错误。你可以用int代替Integer。@Mike-接得好。实际上,我认为在这种特殊情况下,它不会导致错误,但是如果他向他的
addA
实现中添加任何代码,则很可能会导致错误。此外,他不能在
int
上同步,因为它是一个原语,但他可以使用
AtomicInteger
@danben谢谢。我不知道在int上不同步。我想我从来没有尝试过一个原语。你们每天都会学到一些东西,我想我们不应该说同步创建了对象锁,因为其他线程可以在对象锁状态下访问非同步方法。我仍然不明白对象锁定是什么意思?@Thomman:我不知道你说的“对象锁定状态”是什么意思。Java中的每个对象都有自己的互斥体——当您在一个对象上同步时,在线程进入同步块之前,需要保持这个互斥体。
class MyClass extends Thread{
   Test instanceObj=null;    
   public MyClass(Test obj){
      instanceObj=obj;
   }

   public void run(){
      obj.addB();
   }
}
public void addB(){
  synchronized(this){
    //func
 }
}