[英]Synchronized method is not working as expected
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
在您的情况下,进入synchronized
块的thread
将在每次迭代中执行并保留它。 Thread
离开synchronized
块后,它将为另一个竞争thread
留出机会获取lock
并进入synchronized
块。
对于您期望的结果,您可以如下修改MyThread
类的run()
方法。
public void run(){
synchronized(me){
for(int i=0;i<1000;i++){
this.santhu.setName(Thread.currentThread().getName());
}
}
}
同样,如果您按照上述方法操作,则可以从Santhosh
类setName()
方法中删除synchronized
。
PS虽然您应该保留适当的上下文名称,但是我在这里仅出于学习目的理解它,但我仍建议将MyThread
类重命名为MyRunnable
因为它是Runnable
接口的实现,而不是Thread
。
线程以编译器和处理器决定的任何顺序执行。 这包括一个混合的顺序,一个介于2和一个介于1之间。 他们不等待其他线程完成执行。 使用线程时,您应该期望它们同时运行。 它们的行为方式是:同时执行(如果是单核处理器,则交替执行;如果是多核处理器,则同时执行)。 这里没有任何问题。 synchronized
工作正常:它防止线程同时修改字符串(这是应该做的所有事情)。 任何执行顺序都是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.