public class TestCases implements Serializable{
public TestCases() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Santhosh me = new Santhosh();
MyThread myT1 = new MyThread(me);
MyThread myT2 = new MyThread(me);
Thread t1 = new Thread(myT1);
Thread t2 = new Thread(myT2);
t1.setName("one");
t2.setName("two");
t1.start();
t2.start();
}
}
这个类的对象将被两个线程访问
public class Santhosh {
private String name=null;
public void setName(String name){
synchronized(this){
System.out.println("changing name by "+Thread.currentThread().getName());
this.name = name;
}
}
}
我的线程类
public class MyThread implements Runnable{
private Santhosh santhu;
public MyThread(Santhosh me){
this.santhu = me;
}
public void run(){
for(int i=0;i<1000;i++){
this.santhu.setName(Thread.currentThread().getName());
}
}
}
我期望结果是这样的:
changing name by one
changing name by one
changing name by one
.
.
.
(1000 times)
changing name by two
changing name by two
.
.
.
(1000 times)
我知道顺序可能不同,即“更改名称两次”可能会先出现(1000 次),然后“更改名称一位”(1000 次)
但是当我运行这段代码时,我看到这样的东西:
changing name by one
changing name by one
changing name by two
changing name by two
changing name by two
changing name by two
changing name by two
changing name by two
changing name by two
changing name by two
changing name by two
changing name by two
changing name by two
changing name by one --- ONE here
changing name by two
最佳答案
在你的情况下是 thread
输入 synchronized
block ,执行它并将其保留在每次迭代中。一次Thread
离开synchronized
阻止它为另一个竞争者留下了机会thread
获取lock
并输入synchronized
block 。
为了获得您期望的结果,您可以修改类 MyThread
的run()
方法如下。
public void run(){
synchronized(me){
for(int i=0;i<1000;i++){
this.santhu.setName(Thread.currentThread().getName());
}
}
}
此外,如果您按照上述方式操作,则可以删除 synchronized
来自Santhosh
类setName()
方法。
附注虽然你应该保留正确的上下文名称,但我理解这里只是为了学习的目的,但我仍然建议重命名该类 MyThread
至MyRunnable
作为 Runnable
的实现接口(interface),它不是 Thread
.
关于java - 同步方法未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43555917/