线程和同步方法

我有以下代码:

public class MyThread extends Thread { private int i; public static int sum=0; public MyThread(int k){ i=k; } public static void main(String[] args) throws InterruptedException{ Thread t=new MyThread(1); Thread s=new MyThread(2); Thread p=new MyThread(3); t.start(); s.start(); } public synchronized void doSomething(){ for(int i=0; i<100000; i++){ System.out.println(this.i); } } @Override public void run() { doSomething(); } } 

doSomething是同步的。 为什么输出是随机的? 我假设同步方法与同步块相同,但块的输出是同步的,而方法则不是。

synchronized关键字可以防止对同一对象的同步方法调用进行交错。 它不会阻止对不同对象的交错方法调用。 由于您有三个不同的对象,因此三个调用可以同时运行。

您需要在由所有三个线程共享的单个对象上进行同步。

方法上的同步仅适用于同一对象的调用。 您正在创建两个不同的对象(两个线程)。

synchronized方法使用的锁与MyThread类的实例相关联。 由于每个线程都有自己的实例MyThread ,因此每个线程都在自己的锁上进行同步。

如果您想跨所有线程进行同步,您可以执行以下操作:

 public class MyThread extends Thread { private static final Object sharedLock = new Object(); public void doSomething() { synchronized(sharedLock) { for(int i=0; i<100000; i++) { System.out.println(this.i); } } } ... } 

另一种方法是在MyThread.classsynchronize ,但我更喜欢第一种方法。

在评论中,您说如果您将代码更改为在doSomething使用synchronized(this) ,那么它会突然发挥作用。 我很确定它没有。 它可能是偶然的,但它不会重复和可靠地工作。