我们知道没有规定阻止多个线程使用run()
方法调用start()
方法。我创建了两个对象m1
和m2
,它们都调用相同的线程来运行。
我需要通过在第二个对象执行开始之前调用线程来确保第一个对象完成(m1.start
)它的执行。
我的问题是为什么我不能在我创建的帖子中使用synchronized
关键字和run()
方法(例如MyThread1
)?
我尝试在我创建的线程中使用“synchronized”来运行run()方法,但它提供了任意输出(换句话说,m2
不等待m1
完成执行)
你可以在程序的最底部看到我得到的输出。
public class ExtendedThreadDemo {
public static void main(String[] args) {
Mythread1 m1 =new Mythread1();
Mythread1 m2 =new Mythread1();
m1.start();
m2.start();
System.out.println(" main thread exiting ....");
}
}
public class MyThread1 extends Thread {
public synchronized void run() {
for(int i=1; i<5; i++) {
System.out.println(" inside the mythread-1 i = "+ i);
System.out.println(" finish ");
if (i%2 == 0) {
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.println(" the thread has been interrupted ");
}
}
}
}
}
main thread exiting ....
inside the mythread-1 i = 1
finish
inside the mythread-1 i = 2
finish
inside the mythread-1 i = 1
finish
inside the mythread-1 i = 2
finish
inside the mythread-1 i = 3
finish
inside the mythread-1 i = 4
finish
inside the mythread-1 i = 3
finish
inside the mythread-1 i = 4
finish
正如您在i = 2
之后看到的那样,第二个对象(即m2.start()
)开始执行。
答案 0 :(得分:2)
在致电m1.join()
之前致电main
中的m2.start()
。
使方法synchronized
仅影响对相同对象上的方法的多次调用; m1
和m2
是不同的对象,因此添加synchronized
将无效。
答案 1 :(得分:0)
此代码段:
public synchronized void run() {
//code
}
在语义上等同于:
public void run() {
synchronized(this) {
//code
}
}
请注意this
参考。这意味着使用相同synchronized
引用(锁定对象)的所有this
块都是互斥的。但是,您要创建两个线程(对象),每个线程在不同的this
引用上进行同步。
有几种方法可以改善您的代码:
Runnable
并创建两个线程:public class Mythread1 implements Runnable //...
然后:
Runnable r = new Mythread1();
Thread m1 = new Thread(r);
Mythread1 m2 = new Thread(r);
但是这只有在Mythread1
runnable是statelss时才有效,因为它将由两个线程共享。
将一些任意lock
对象传递给Mythread1
的两个实例,然后使用:
synchronized(lock) {
//code
}
从Java 5开始,有更复杂的方法来同步代码,但这个方法适用于简单的情况。
Thread.join()
您可以致电:
m1.start();
m1.join();
m2.start();
这样就可以了。
答案 2 :(得分:0)
同步实例方法仅阻止对该类的同一实例的并发访问。如果run方法是静态的,您会看到预期的效果。但我不建议将run方法设为静态。事实上,如果要保持其当前功能,则不能。您应该考虑使用m1.join()
等待m1完成。如果您有多个要相互等待的线程,那么另一种更好的方法是使用CyclicBarrier或CountDownLatch。