[英]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();
}
}
This is class whose object would be accessed by two threads 该类的对象将由两个线程访问
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());
}
}
}
I was expecting result to be like: 我期望结果是这样的:
changing name by one
changing name by one
changing name by one
.
.
.
(1000 times)
changing name by two
changing name by two
.
.
.
(1000 times)
I know sequence could be different ie. 我知道顺序可能会不同。 'Changing name by two' could come first (1000 times) and then 'Changing name by one' (1000 times)
“先改名”(1000次)然后是“先改名”(1000次)
But when I run this code I see something like this: 但是,当我运行这段代码时,我看到的是这样的:
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
In your case a thread
on entering the synchronized
block, executes it and leaves it in each iteration. 在您的情况下,进入
synchronized
块的thread
将在每次迭代中执行并保留它。 Once a Thread
leaves the synchronized
block it leaves an opportunity for another competiting thread
to aquire lock
and enter the synchronized
block. Thread
离开synchronized
块后,它将为另一个竞争thread
留出机会获取lock
并进入synchronized
块。
For the result you expect you may modify the class MyThread
's run()
method as below. 对于您期望的结果,您可以如下修改
MyThread
类的run()
方法。
public void run(){
synchronized(me){
for(int i=0;i<1000;i++){
this.santhu.setName(Thread.currentThread().getName());
}
}
}
Also if you follow above way then you can remove the synchronized
from Santhosh
class setName()
method. 同样,如果您按照上述方法操作,则可以从
Santhosh
类setName()
方法中删除synchronized
。
PS Though you should keep proper contextual names but I understand here its just for the purpose of study but still I would suggest to rename the class MyThread
to MyRunnable
as its an implementation of Runnable
interface and its not a Thread
. PS虽然您应该保留适当的上下文名称,但是我在这里仅出于学习目的理解它,但我仍建议将
MyThread
类重命名为MyRunnable
因为它是Runnable
接口的实现,而不是Thread
。
Threads execute in whatever order the compiler and the processor decide. 线程以编译器和处理器决定的任何顺序执行。 This includes a mixed order, with ones between twos and twos between ones.
这包括一个混合的顺序,一个介于2和一个介于1之间。 They don't wait for other threads to finish before executing.
他们不等待其他线程完成执行。 When using threads, you should expect them running at the same time.
使用线程时,您应该期望它们同时运行。 This is how they're supposed to behave: executing at the same time (alternating if single-core processor, concurrently if multi-core processor).
它们的行为方式是:同时执行(如果是单核处理器,则交替执行;如果是多核处理器,则同时执行)。 There isn't anything wrong here.
这里没有任何问题。
synchronized
is working correctly: it prevents the threads from modifying the string at the same time (that's all it's supposed to do). synchronized
工作正常:它防止线程同时修改字符串(这是应该做的所有事情)。 Any execution order is correct. 任何执行顺序都是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.