Java 同步使对象锁定
我对对象锁有点困惑。 下面的类有4个方法,方法addB()是同步的 在我的scienario中,有4个线程。当一个线程2访问addB()方法(它在测试对象上创建了一个锁)时,是否会有其他线程同时访问addC()或addD() 对象锁一次只允许一个线程吗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
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
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
}
}