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;
}
}
}
My Thread class
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)
我知道序列可能有所不同,例如“将名字改为2”可以先来(1000次),然后“将名字改为1”(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
答案 0 :(得分:1)
在你的情况下,thread
进入synchronized
块,执行它并在每次迭代中离开它。一旦Thread
离开synchronized
广告块,就会有机会让其他竞争对手thread
获取lock
并输入synchronized
广告块。
对于您希望的结果,您可以修改类MyThread
的{{1}}方法,如下所示。
run()
此外,如果您按照上述方式操作,则可以从public void run(){
synchronized(me){
for(int i=0;i<1000;i++){
this.santhu.setName(Thread.currentThread().getName());
}
}
}
类synchronized
方法中移除Santhosh
。
P.S。虽然你应该保留适当的上下文名称但我在这里理解它只是为了研究的目的,但我仍然建议将类setName()
重命名为MyThread
作为MyRunnable
接口的实现它不是Runnable
。
答案 1 :(得分:0)
线程以编译器和处理器决定的顺序执行。这包括混合顺序,两者之间有两个和两个之间的顺序。在执行之前,他们不会等待其他线程完成。使用线程时,您应该期望它们同时运行。这就是它们应该如何表现的行为:同时执行(如果是单核处理器则交替,如果是多核处理器则同时执行)。这里没有任何错误。 synchronized
正常工作:它可以防止线程同时修改字符串(这就是它应该做的所有事情)。任何执行顺序都是正确的。