在这个多线程程序中,线程" t1"和" t2"正在尝试在同一个对象obj上执行同步方法printTable()
。当t1启动并且从printTable()
方法调用run()
时,t2必须等到t1完成同步方法的执行;为什么这不会发生?为什么输出未排序?
以下是该计划:
class Table{
void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
//Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
public class TestSynchronization3{
public static void main(String args[]){
final Table obj = new Table();//only one object
Thread t1=new Thread(){
public void run(){
obj.printTable(5);
}
};
Thread t2=new Thread(){
public void run(){
obj.printTable(100);
}
};
t1.start();
t2.start();
}
}
答案 0 :(得分:4)
您需要在synchronized
指出的printTable()
方法中添加关键字Table
,如Michael所述。从
printTable()
的签名
void printTable(int n){...}
到
synchronized void printTable(int n){...}
这会将输出生成为:
100
200
300
400
500
5
10
15
20
25
或
5
10
15
20
25
100
200
300
400
500
答案 1 :(得分:0)
为什么不发生这种情况?为什么输出未排序?
虽然正如其他评论和答案所提到的那样,你需要使用synchronized
关键字,我怀疑你真正的问题是你不了解线程的竞争条件。
仅仅因为您在代码中的obj.printTable(5);
线程之前启动obj.printTable(100);
线程,这并不能确保线程按该顺序运行。正如@user5794376所示,当两个线程开始时,有一个竞赛,看看谁是第一个调用printTable(...)
的人,然后谁必须等待另一个线程完成。线程以异步方式运行,无法预测哪一个会获胜并保证订单。
如果你需要强制输出的顺序那么问题就变成了,你为什么要使用线程,除非这是某种学术练习。线程的全部意义在于它们以异步方式并行运行。用于控制其操作顺序的任何措施(如锁定或信令)都会使其整个目的无效。
要尝试的另一件事是从两个线程运行printTable(...)
而根本没有同步。 System.out.println(...)
是一种同步方法,所以很好。您可能会看到相同的输出,因为在另一个线程开始之前,一个线程再次获取并运行其所有5个println(...)
语句。如果你真的想看到交错,那么你应该增加5到5000000.然后你应该看到*5
输出的块然后是*100
输出的块。
希望这有帮助。