繁体   English   中英

关于多线程的测验

[英]Quiz about multi-threading

这是几年前在 IBM'developerworks 站点上发布的关于多线程的测验,现在不可用。

测验问: 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();
    }
}

我想,问题是两个线程都使用了相同的Runnable并且它自己同步。 因此线程实际上不能并行执行stepAstepB 要解决此问题,您可以创建两个HelloRun实例:

Thread t1 = new Thread(new HelloRun(), "one");
Thread t2 = new Thread(new HelloRun(), "two");

或者删除synchronized关键字。

唯一的问题是您可以在同步块之外交错消息:

>>> 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。

相反,如果您可以毫无问题地交错操作,则可以从 stepA 和 stepB 中删除同步。

在我看来,这是一个设计问题。 如果你想让两个线程做不同的事情,它不应该在一个类中实现。 有一个干净的代码原则称为关注点分离

此外,代码包含幻数 一旦你更改了一个线程的名称,它会做一些完全不同的事情,这是完全出乎意料的。

正如Stephen C所提到的,您无法真正说出代码应该做什么,因此很难说它是否正确以及需要修复哪些错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM