美文网首页
记一次面试用wait与notify实现多线程

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

作者: nhhnhh | 来源:发表于2020-04-16 23:12 被阅读0次

    有次面试的时候要手写代码,题目是将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的理解是多少。

    相关文章

      网友评论

          本文标题:记一次面试用wait与notify实现多线程

          本文链接:https://www.haomeiwen.com/subject/sobjvhtx.html