我有以下代码:
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块相同但块的输出是同步的,方法不是。
答案 0 :(得分:9)
synchronized
关键字阻止对同一对象的同步方法调用进行交错。它不会阻止对不同对象的交错方法调用。由于您有三个不同的对象,因此三个调用可以同时运行。
您需要同步所有三个线程共享的单个对象。
答案 1 :(得分:1)
方法上的同步仅适用于同一对象的调用。您正在创建两个不同的对象(两个线程)。
答案 2 :(得分:0)
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);
}
}
}
...
}
另一种选择是synchronize
MyThread.class
,但我更喜欢第一种方法。
在评论中,您说如果您在synchronized(this)
中更改代码以使用doSomething
,那么它会突然发挥作用。我很确定它没有。它可能是偶然的,但它不会重复和可靠地工作。