一道考察线程协作的Java面试题

题目:启动 3 个线程,第一个线程打印 0,第二个打印 1,第三个打印 2,然后第一个线程打印 3,依次类推,直到打 印指定的数字为止,例如 20;

我这里为了方便,不用三个线程,直接用连个线程代替,其实方法一样的,主要理解思想

方法1: 用 wait/notifyAll
public void method1() {
    LinkedList<Integer> integers = new LinkedList<>();
    for (int i = 0; i < 20; i++) {
        integers.add(i);
    }
​
    new Thread(() -> {
        while (!integers.isEmpty()) {
            synchronized (integers) {
                //解释一下这里为什么还要判断一下非空,可能你第一次进来非空,然后不满足条件,当前线程被阻塞释放放资源,                    
          //等其他线程执行完之后,释个时候,队列中不一定是非空的
                while (!integers.isEmpty() && integers.getLast() % 2 == 0) {
                    try {
                        integers.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (integers.isEmpty()){
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "打印:" + integers.getLast());
                integers.removeLast();
                integers.notifyAll();
            }
        }
    }, "thread1").start();
​
    new Thread(() -> {
        while (!integers.isEmpty()) {
            synchronized (integers) {
                while (!integers.isEmpty() && integers.getLast() % 2 == 1) {
                    try {
                        integers.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (integers.isEmpty()){
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "打印:" + integers.getLast());
                integers.removeLast();
                integers.notifyAll();
            }
        }
    }, "thread2").start();
​
}

 

//方法2 用park/unpark
public void method2() {
​
        Thread[] threads = new Thread[2];
​
        Thread thread1 = new Thread(() -> {
            while (!integers.isEmpty()) {
                if (!integers.isEmpty() && integers.getFirst() % 2 == 0) {
                    LockSupport.park();
                }
                if (integers.isEmpty()) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "打印:" + integers.pop());
                LockSupport.unpark(threads[1]);
            }
        }, "线程1");
        Thread thread2 = new Thread(() -> {
            while (!integers.isEmpty()) {
                while (!integers.isEmpty() && integers.getFirst() % 2 == 1) {
                    LockSupport.park();
                }
                if (integers.isEmpty()) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "打印:" + integers.pop());
                LockSupport.unpark(threads[0]);
            }
        }, "线程2");
​
        threads[0] = thread1;
        threads[1] = thread2;
        thread1.start();
        thread2.start();
    }

 

 
posted @ 2023-01-13 15:15  刘阿泽  阅读(27)  评论(0编辑  收藏  举报