基本10家公司面试,7家都会考多线程~~我们直接看下面的代码↓↓↓↓
public class WaitNotifyOne {
private volatile static List<String> list = new ArrayList<>();
public void add() {
list.add("hello,world");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
final WaitNotifyOne waitNotify01 = new WaitNotifyOne();
Thread thread1 = new Thread(new Runnable() {
public void run() {
try {
for (int i = 0; i < 10; i++) {
waitNotify01.add();
System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread thread2 = new Thread(new Runnable() {
public void run() {
while (true) {
if (waitNotify01.size() == 5) {
System.out.println(Thread.currentThread().getName() + "收到通知..");
System.out.println(Thread.currentThread().getName() + "退出..");
break;
}
}
}
}, "t2");
thread2.start();
thread1.start();
}
}
从代码看很简单,就是thread2先启动线程,然后死循环判断size的大小,如果是5就输出打印,然后thread1就是循环加元素.下面是打印结果↓↓↓↓↓
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
t2收到通知..
t2退出..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
从上面的代码来看,thread2是读了一个死循环,这在程序中是很占用资源的,于是有了notify()和wait(),上代码~~
public class WaitNotifyTwo {
private volatile static List<String> list = new ArrayList<>();
public void add() {
list.add("hello,world");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
final WaitNotifyTwo waitNotifyTwo = new WaitNotifyTwo();
final Object object = new Object();
Thread thread1 = new Thread(new Runnable() {
public void run() {
synchronized (object) {
try {
for (int i = 0; i < 10; i++) {
waitNotifyTwo.add();
System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
Thread.sleep(500);
if (waitNotifyTwo.size() == 5) {
System.out.println(Thread.currentThread().getName() + "发起通知..");
object.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "t1");
Thread thread2 = new Thread(new Runnable() {
public void run() {
synchronized (object) {
if (waitNotifyTwo.size() != 5) {
try {
System.out.println(Thread.currentThread().getName() + "等待中..");
object.wait();
System.out.println(Thread.currentThread().getName() + "收到通知..");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程:" + Thread.currentThread().getName() + "收到通知线程停止..");
throw new RuntimeException();
}
}
}
}, "t2");
thread2.start();
thread1.start();
}
}
首先理论知识,notify()和wait()方法一般要结合synchronized去使用,wait()方法释放锁,线程堵塞(即不继续执行),而notify()不释放锁,既然不释放锁了,所以肯定继续执行. notify()表示通知唤起,唤起的对象和wait()的对象必须是同一个才有效,如果还不懂啥意思百度~
然后我们看上面的代码,分析一下,首先thread2开启(为什么一定要thread2先开,自己动脑子),thread2获得object对象的锁,判断长度大小不是5,所以最开始打印的是-->t2等待中,然后调用wait()方法进行堵塞,并且释放锁.thread1获得object对象锁,输出打印-->t1添加了一个元素..当size()等于5的时候,打印-->t1发起通知,,但是notify()不释放锁,所以会继续打印thread1添加了一个元素,,当thread1线程执行结束,thread2 输出 -->t2收到通知 ,t2收到通知线程停止,,,,
看下面的打印结果↓↓↓↓↓
t2等待中..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
t1发起通知..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
t2收到通知..
当前线程:t2收到通知线程停止..
看,就像分析的,就是这么简单!!!!!!!!!!!!!
看了上面的,我们会发现,第二种方案不能像第一种一样可以做到实时通知,如果用第一种我们cpu的负荷会很大,于是就有了下面优化版的,使用的是java.util.concurrent类,此类之强大,@#$%^&*()_()&%$,佩服万分~~~
上代码~~
public class WaitNotifyThree {
private volatile static List<String> list = new ArrayList<>();
public void add() {
list.add("hello,world");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
final WaitNotifyThree waitNotifyThree = new WaitNotifyThree();
final CountDownLatch countDownLatch = new CountDownLatch(1);
Thread thread1 = new Thread(new Runnable() {
public void run() {
try {
for (int i = 0; i < 10; i++) {
waitNotifyThree.add();
System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
Thread.sleep(500);
if (waitNotifyThree.size() == 5) {
System.out.println(Thread.currentThread().getName() + "发起通知..");
countDownLatch.countDown();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread thread2 = new Thread(new Runnable() {
public void run() {
if (waitNotifyThree.size() != 5) {
try {
System.out.println(Thread.currentThread().getName() + "等待中..");
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "收到通知..");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "收到通知线程停止..");
}
}
}, "t2");
thread2.start();
thread1.start();
}
}
然后运行结果↓↓↓↓↓↓↓↓↓↓↓↓将来讲~~~~~~~
t2等待中..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
t1发起通知..
当前线程:t1添加了一个元素..
t2收到通知..
t2收到通知线程停止..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
当前线程:t1添加了一个元素..
有啥不懂的请加qq727865942,微信号 cto_zej,觉得是干货请打赏~~~~~~~~~~
网友评论