关于多线程的测验

时间:2015-09-22 09:02:10

标签: java multithreading

这是几年前在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();
    }
}

3 个答案:

答案 0 :(得分:3)

我想,问题是两个线程使用相同的Runnable并且它自身同步。因此,线程实际上不能并行执行stepAstepB。要解决此问题,您可以创建两个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固定的。