多线程如何在Java中为对象的不同成员拥有不同的同步块
我试图理解java中的同步块
在C/C++中,我们使用互斥来保护关键部分。所以,如果一个对象有两个资源,比如i和j,如果有两个接口SetI和SetJ分别修改i和j,我会声明两个互斥体,每个互斥体保护i和j,很简单
现在我正试图用java模拟同样的事情
考虑一个进入同步(OBJ)的线程,并希望修改它的成员I.P/P>
那么,我可以不让另一个线程进入一个不同的同步块,但属于同一个对象,它需要修改obj的另一个名为j的成员吗
我附上了一个示例代码,它试图执行上述任务,但只有一个线程获得了机会,而另一个想要修改其他变量的线程从未获得机会
如果要保护的资源是对象,我会对成员本身i和j进行同步。但由于这些是原始数据类型,我无法在同步中使用它们(我尝试了,但出现了编译错误)。因此,我被迫在“this”上同步
问题不在于我理解为什么只有一个线程有机会执行。相反,我如何实现我的需求,即“两个线程修改一个对象的两个不同资源不应该相互阻塞”
class object
{
private boolean i;
private boolean j;
public void flipi(String arg)
{
synchronized(this)
{
while(true)
{
i = !i;
System.out.println("flipi "+ "thread: " + arg + " value of i: " + i);
try
{
Thread.sleep(2000);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
}
public void flipj(String arg)
{
synchronized(this)
{
while(true)
{
j = !j;
System.out.println("flipj "+ "thread: " + arg + " value of j: " + j );
try
{
Thread.sleep(2000);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
}
}
class test extends Thread
{
object obj;
test(object obj)
{
this.obj = obj;
}
@Override
public void run()
{
String threadname = Thread.currentThread().getName();
if(threadname.equals("test1"))
{
obj.flipi(Thread.currentThread().getName());
}
else if(threadname.equals("test2"))
{
obj.flipj(Thread.currentThread().getName());
}
}
}
public class testsynchronized
{
public static void main(String[] args)
{
object obj = new object();
test t1 = new test(obj);
test t2 = new test(obj);
t1.setName("test1");
t2.setName("test2");
t1.start();
t2.start();
}
}
输出:
$ java testsynchronized
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
flipj thread: test2 value of j: false
flipj thread: test2 value of j: true
# 1 楼答案
您可以创建两个不同的锁定对象并在其上同步,而不是在“this”上同步:
# 2 楼答案
在同步块中有一个无限循环,它们都在同一个对象上同步(
this
)。一旦一个线程进入,它就永远不会离开,因此其他线程都不能进入同步块要允许不同线程在不相互干扰的情况下更新不同的变量,请在不同的事情上同步这些变量的更新:
然后:
及
顺便说一句,在线程名上切换行为基本上从来都不是正确的做法。只需创建如下线程:
# 3 楼答案
你可以看到
正在为调用
flipi("threadName")
的run()方法运行 也就是说它从不打电话只有第一个
flipi
方法在循环中运行要理解这一点,请尝试其他方法,而不是进入无限循环