记一次面试用wait与notify实现多线程

2020-04-16  本文已影响0人  nhhnhh

有次面试的时候要手写代码,题目是将100万个数用10个线程相加。
首先想到的是用countDownLatch做。

public class AddNumbersByThreadsCountDownLatch extends Thread{
    private long startNum;
    private AtomicLong sumNumbers;
    private CountDownLatch countDownLatch;

    public AddNumbersByThreadsCountDownLatch (long startNum,  AtomicLong sumNumbers, CountDownLatch countDownLatch){
        this.startNum = startNum;
        this.sumNumbers = sumNumbers;
        this.countDownLatch = countDownLatch;
    }

    public void run() {
        long sum = 0;
        for (long i = 0; i<100000; i++){
            sum = startNum + sum + i;
        }
        System.out.println("sum:" + sum);
        sumNumbers.getAndAdd(sum);
        countDownLatch.countDown();
    }

    public static void main(String[] args) throws Exception {
        Thread[] threadList = new Thread[10];
        CountDownLatch countDownLatch = new CountDownLatch(10);
        AtomicLong sumNumber = new AtomicLong();
        for (int i = 0; i<10; i++){
            threadList[i] = new AddNumbersByThreadsCountDownLatch(1000000*i, sumNumber, countDownLatch);
            threadList[i].start();
        }
        countDownLatch.await();
        System.out.println("sum number is " + sumNumber);
    }
}

做完后,面试官让用wait,跟notify再实现一把。当时想茬了,也是对wait跟notify的使用不够精通,卡了好久才写出来。最开始的想法是一个线程一个线程的去唤醒然后相加,这个想法现在想想太蠢了。

public class AddNumbersByThreads {
    public static void main(String[] args) throws Exception {
        long sum = 0;
        //定义10把锁
        Object[] lock = new Object[10];
        for (int i =0;i<10;i++){
            lock[i] = new Object();
        }
        List<Add> addList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            //开10个线程,然后放到list里存起来
            Add add = new Add(100000 * i, lock[i]);
            add.start();
            addList.add(add);
        }
        //进行wait
        for (int i = 0; i < 10; i++) {
            synchronized (lock[i]) {
                //防止提前通知
                while (!addList.get(i).getHasNotify()){
                    lock[i].wait();
                }
            }
        }
        //全部算好数值后相加
        for (Add add : addList) {
            sum += add.getSumNumber();
        }
        System.out.println("sum number is " + sum);
    }
}
class Add extends Thread{
    private long startNum;
    private volatile long sumNumber;
    private volatile boolean hasNotify;
    public long getSumNumber() {
        return sumNumber;
    }
    public boolean getHasNotify() {
        return hasNotify;
    }
    private  Object lock;
    public Add(long startNum ,Object lock){
        this.startNum = startNum;
        this.lock = lock;
    }
    public void run() {
        long sum = 0;
        synchronized (lock){
            for (int i = 100000;i >0; i--){
                sum = sum + startNum + i;
                i --;
            }
            sumNumber = sum;
            hasNotify = true;
            lock.notify();
        }
    }
}

写的时候才知道自己对于volatile以及wait与object的理解是多少。

上一篇下一篇

猜你喜欢

热点阅读