Java 多线程测验

Java 多线程测验,java,multithreading,Java,Multithreading,这是几年前在IBM的developerworks站点上发布的一个关于多线程的测验,现在还没有 提问是这样的: 1.这个代码有什么问题 2.如何改进此代码 我想知道这个测验的确切答案是什么 class HelloRun implements Runnable{ @Override public void run() { System.out.println( ">>>" + Thread.currentThread().getName() + ":

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

唯一的问题是,您可以从同步块中交错消息:

>>> one: started
>>> two: started
started B
Do something B
end B
started A
Do something A
end A

要解决这种交织问题,可以将synchronized添加到run方法,而不是stepA和stepB


相反,如果您可以在没有问题的情况下交错操作,那么您可以从stepA和stepB中删除synchronized。

我想,问题是相同的
Runnable
用于两个线程,并且它在自身上进行同步。因此线程实际上不能并行执行
stepA
stepB
。要解决此问题,您可以创建两个
HelloRun
实例:

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

或者删除同步的关键字。

在我看来,这是一个设计问题。如果希望两个线程执行不同的操作,则不应在一个类中实现。有一个干净的代码原则叫做

此外,代码还包含。一旦更改了线程的名称,它就会执行完全不同的操作,这是完全出乎意料的


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

什么答案?它将打印stepA()和stepB()打印语句。不需要同步,所以性能会很好。您运行了吗@virendrao:System.out.println的性能?@Thomas我在告诉你为什么我们需要在方法中“同步化”?同步化:以避免在标准输出中混淆行三元组。这是一个非常糟糕的测验问题,我不会浪费时间尝试解决它。问题是,既然测验没有说明代码应该做什么,我们就不能说它到底出了什么问题synchronized@virendrao,如果假定它是某个更大任务的一部分,则可能需要同步。当前代码无论如何都是无用的,因为
System.out.println
也是同步的,因此启动线程只是为了将某些内容打印到stdout是一个疯狂的想法。@virendrao-除非我们知道代码应该做什么,否则我们不能这么说。我们只是不知道。是的,但这里只有印刷品这就是为什么我说它。。。但是,如果只有一个runnable,那么在这种情况下,当它在一个runnable对象上同步时,两个线程如何不等待对方呢
>>> one: started
started B
Do something B
end B
>>> two: started
started B
Do something B
end B
Thread t1 = new Thread(new HelloRun(), "one");
Thread t2 = new Thread(new HelloRun(), "two");