线程输出播放器

时间:2016-04-18 20:14:24

标签: java multithreading static

有人可以告诉我这段代码的输出是什么以及为什么?我自己尝试过,但它不会起作用。

public static class Player extends Thread {
    int id;
    Player op;

    public Player(int n){
        id = n;
    }

    public void connect(Player other) {
        op = other;
    }

    public void run() {
        if(op != null) {
            try {
                op.join();
            } catch (InterruptedException ex) {
                System.out.println(" INTERRUPTED");
            }
        }
        System.out.println("PLAYER ID ="+id);
    }

    public static void main(String[] args) {
        Player p1=new Player(1);
        Player p2=new Player(2);
        p1.connect(p2);
        p1.start();
        p2.start();
    }
}

1 个答案:

答案 0 :(得分:0)

首先,你不能在类上使用静态修饰符,除非它嵌套在另一个类中,所以你所拥有的不会编译。一旦你通过删除static关键字来修复它,程序就会运行并打印出来:

PLAYER ID =2
PLAYER ID =1

主线程初始化p1和p2线程,启动它们并退出。线程是非守护程序线程,因此JVM会一直运行直到它们完成。

p1线程在p2线程上调用join,导致p1进入休眠状态,直到p2结束。 p2将其op字段设置为null,因此它执行,打印输出并完成(在终止时通知p1)。此时p1从等待p2唤醒,打印输出并终止。

因此只要一个线程在另一个线程上调用connect,连接线程就会在打印输出之前等待另一个线程完成。如果在启动线程之前添加一行p2.connect(p1);,那么当两个线程永远等待彼此时,你应该会遇到死锁。

p1不能保证在p2之前启动。如果p2碰巧首先执行其run方法,那么p1将加入一个死线程,因此它不必等待;无论哪个线程首先开始,结果都是相同的(p2先完成)。