记一次面试用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的理解是多少。