繁体   English   中英

同步方法无法正常工作

[英]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());
          }
    }
  }

同样,如果您按照上述方法操作,则可以从SanthoshsetName()方法中删除synchronized

PS虽然您应该保留适当的上下文名称,但是我在这里仅出于学习目的理解它,但我仍建议将MyThread类重命名为MyRunnable因为它是Runnable接口的实现,而不是Thread

线程以编译器和处理器决定的任何顺序执行。 这包括一个混合的顺序,一个介于2和一个介于1之间。 他们不等待其他线程完成执行。 使用线程时,您应该期望它们同时运行。 它们的行为方式是:同时执行(如果是单核处理器,则交替执行;如果是多核处理器,则同时执行)。 这里没有任何问题。 synchronized工作正常:它防止线程同时修改字符串(这是应该做的所有事情)。 任何执行顺序都是正确的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM