线程未按预期执行

时间:2018-08-17 09:27:47

标签: java multithreading junit

我写了一个简单的多线程程序,但是没有以预期的方式运行。

public class LockTest {

    private Lock lock = new ReentrantLock();

    @Test
    public void maintest(){
        System.out.println("main program");
        LockTest lockTest = new LockTest();
        Thread a = new Thread(){
            @Override
            public void run(){
                System.out.println("thread a");
                lockTest.process();
            }
        };

        Thread b = new Thread(){
            @Override
            public void run(){
                System.out.println("thread b");
                lockTest.process();
            }
        };

        a.start();
        b.start();
    }

    public void process(){
        System.out.println("start process");
        int i = 0;
        boolean result = false;
        do {
            i++;
            result = lock.tryLock();
            System.out.println(result + " " + i);
        }while (!result && i < 3);
        if (!result){
            System.out.println("get no lock");
            return;
        }
        try {
            System.out.println("get lock");
            System.out.println("process aaa");
            System.out.println("process bbb");
            Thread.sleep(1000);

            System.out.println("process ddd");
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            lock.unlock();
            System.out.println("release lock");
        }
    }
}

输出并不总是相同的。有时只显示:

Connected to the target VM, address: '127.0.0.1:50858', transport: 'socket'
main program

Disconnected from the target VM, address: '127.0.0.1:50858', transport: 'socket'

Process finished with exit code 0

或显示结果:

Connected to the target VM, address: '127.0.0.1:50935', transport: 'socket'
main program
thread b
thread a
start process
start process
false 1
true 1
get lock
process aaa
process bbb
false 2
false 3
get no lock
Disconnected from the target VM, address: '127.0.0.1:50935', transport: 'socket'

Process finished with exit code 0

为什么程序不执行全部代码?将IntelliJIdea与Java 8,JUnit测试结合使用

2 个答案:

答案 0 :(得分:1)

添加

a.join();
b.join();

启动两个胎面之后。

它会等到胎面完成为止。

答案 1 :(得分:0)

Connected to the target VM, address: '127.0.0.1:50935', transport: 'socket'

在Java调试器调试JVM的端口时打印。

Disconnected to the target VM, address: '127.0.0.1:50935', transport: 'socket'

由于Java调试器不再执行或只是将应用程序结束而在应用程序结束时打印。

从本质上来说,该应用有时有时会在其他线程获得CPU时间之前完成。为了确保 main 线程等待其他线程完成(这意味着他们收到CPU时间来完成各自的run()方法),请利用线程方法join()。这将导致调用线程(在本例中为 main 线程)等待该线程的完成。

由于多线程的性质,多线程可能会产生不同的结果。中断,交换,资源分配等等决定了线程何时执行以及何时等待CPU时间。现在请记住,当计算机在执行线程之间切换时,这些等待时间是微观时间。

如果您希望应用程序每次运行都能产生相同的结果,那么您正在寻找确定性多线程,并且需要仔细的同步和设计才能完成。如果您希望每次都以相同的顺序运行逻辑,则不应该使用多线程,否则将需要过于完整的条件来抵消 power 多线程。