这是几年前在IBM&developerWorks网站上发布的多线程测验,现在无法使用。
quize问: 1.这段代码的问题是什么? 2.如何改进此代码
我想知道这个测验的确切答案是什么。
class HelloRun implements Runnable{
@Override
public void run() {
System.out.println( ">>>" + Thread.currentThread().getName() + ": started");
if( Thread.currentThread().getName().equals("one") ){
stepA();
} else {
stepB();
}
}
private synchronized void stepB() {
System.out.println("started B");
System.out.println("Do something");
System.out.println("end B");
}
private synchronized void stepA() {
System.out.println("started A");
System.out.println("Do something");
System.out.println("end A");
}
public static void main(String[] args) {
HelloRun helloRun = new HelloRun();
Thread t1 = new Thread(helloRun, "one");
Thread t2 = new Thread(helloRun, "two");
t1.start();
t2.start();
}
}
答案 0 :(得分:3)
我想,问题是两个线程使用相同的Runnable
并且它自身同步。因此,线程实际上不能并行执行stepA
和stepB
。要解决此问题,您可以创建两个HelloRun
实例:
Thread t1 = new Thread(new HelloRun(), "one");
Thread t2 = new Thread(new HelloRun(), "two");
或删除synchronized
个关键字。
答案 1 :(得分:0)
唯一的问题是您可以将消息交错出同步块:
>>> one: started
>>> two: started
started B
Do something B
end B
started A
Do something A
end A
或
>>> one: started
>>> two: started
started A
Do something A
end A
started B
Do something B
end B
或
>>> one: started
started B
Do something B
end B
>>> two: started
started B
Do something B
end B
要解决此交错,您可以将synchronized同步添加到run方法,而不是stepA和stepB。
相反,如果您可以毫无问题地交错操作,则可以从步骤A和步骤B中删除同步。
答案 2 :(得分:0)
在我看来,这是一个设计问题。如果你想让两个线程做不同的事情,它不应该在一个类中实现。这是一个名为separation of concerns的干净代码原则。
此外,代码包含magic numbers。一旦你更改了一个线程的名称,它就会完全不同,这是完全出乎意料的。
正如Stephen C所提到的,你无法真正告诉代码应该做什么,所以很难说它是否正确以及需要做什么bug固定的。