【java进阶】-多线程面试题-condition和singal的实际运用考察

题目是这样的:启动4个线程,第一个线程打印1,2;第二个线程打印3,4;第三个线程打印5,6;第四个线程打印7,8;然后第一个线程打印9,10...如此循环下去直到打印出100即终止.

刚拿到这个题目的时候,觉得好简单啊(眼高手低...),面试官要求直接把代码写在纸上,于是开始一顿猛如虎的操作,接下来就越来越尴尬了,首先脱离了编辑器差点线程池的创建的单词都拼错...然后写了一段自己都觉得Low的代码,虽然功能是实现了,但面试官看到并不满意,因为这道题他出题的意图应该是在考察jdk1.5 concurren包下的condition和signal方法,而我压根就没有用condition和signal,我误以为是要考察线程池和callable及future的知识,然后通过这种方式用了好几条if,实现的一点不优雅.直到最后出来坐在地铁上思考才恍然大悟,为啥不用condition呢?因为不想让犯过的错再犯第二遍,所以特写此篇总结一下.

首先需要创建一把悲观锁,然后需要为四个线程分别创建各自的condition.再定义全局的数值用于打印1-100,每次打印后自增,最后一样就是全局的condition控制器(用具体的数值来保证每次休眠和唤醒哪几个线程),废话不多说,还是直接上代码:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class T {
    private Integer curNum = 1;
    private Integer no = 1;
    private final Lock lock = new ReentrantLock();
    private final Condition condition1 = lock.newCondition();
    private final Condition condition2 = lock.newCondition();
    private final Condition condition3 = lock.newCondition();
    private final Condition condition4 = lock.newCondition();

    public void printNum() {
        if (curNum > 100) {
            Thread.currentThread().interrupt();
            return;
        }
        for (int i = 0; i < 2; i++) {
            System.out.println(Thread.currentThread().getName() + " : " + (curNum++));
        }
    }

    public void process1() {
        lock.lock();
        try {
            while (no != 1)
                condition1.await();
            printNum();
            no = 2;
            condition2.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void process2() {
        lock.lock();
        try {
            while (no != 2)
                condition2.await();
            printNum();
            no = 3;
            condition3.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void process3() {
        lock.lock();
        try {
            while (no != 3)
                condition3.await();
            printNum();
            no = 4;
            condition4.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void process4() {
        lock.lock();
        try {
            while (no != 4)
                condition4.await();
            printNum();
            no = 1;
            condition1.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        final T t = new T();
        new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                t.process1();
            }
        }).start();
        new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                t.process2();
            }
        }).start();
        new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                t.process3();
            }
        }).start();
        new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                t.process4();
            }
        }).start();
    }
}

结果完全符合预期:

【java进阶】-多线程面试题-condition和singal的实际运用考察_第1张图片

 

你可能感兴趣的:(【面试题】)