一道考察线程协作的Java面试题
我这里为了方便,不用三个线程,直接用连个线程代替,其实方法一样的,主要理解思想
方法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(); }