1、線程通信概念
線程是操作系統(tǒng)中獨(dú)立的個(gè)體,但這些個(gè)體如果不經(jīng)過(guò)特殊的處理就不能成為一個(gè)整體,線程間的通信就成為整體的必勝方式之一。當(dāng)線程存在通信指揮,系統(tǒng)間的交互性更強(qiáng)大,在提高CPU利用率的同時(shí)還會(huì)使開(kāi)發(fā)人員對(duì)線程任務(wù)在處理的過(guò)程中進(jìn)行有效把握與監(jiān)控。
使用wait/notify
方法實(shí)現(xiàn)線程間的通信。都是Object
類(lèi)的方法
-
wait/notify
必須配合synchronized
關(guān)鍵字使用,wait
方法釋放鎖,notify
方法不釋放鎖,會(huì)導(dǎo)致不實(shí)時(shí) - 采用
CountDownLatch
可以實(shí)現(xiàn)實(shí)時(shí)通知。不需要加鎖,countDown
類(lèi)似于notify
,await
類(lèi)似于wait
,實(shí)現(xiàn)兩個(gè)線程一個(gè)等待,一個(gè)喚醒。
package demo1;
import java.util.ArrayList;
import java.util.List;
import javax.management.RuntimeErrorException;
public class ListAdd2 {
private volatile static List list = new ArrayList();
public void add() {
list.add("bjsxt");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
final ListAdd2 list2 = new ListAdd2();
final Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
synchronized (lock) {
for (int i = 0; i < 10; i++) {
list2.add();
System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + "添加了一個(gè)元素..");
Thread.sleep(500);
if (list2.size() == 5) {
System.out.println("已經(jīng)發(fā)出通知..");
lock.notify();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
if (list2.size() != 5) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + "收到通知,線程停止..");
throw new RuntimeException();
}
}
}, "t2");
t2.start();
t1.start();
}
}
package demo1;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class ListAdd3 {
private volatile static List list = new ArrayList();
public void add() {
list.add("bjsxt");
}
public int size() {
return list.size();
}
public static void main(String[] args) {
final ListAdd3 list2 = new ListAdd3();
final CountDownLatch countDownLatch = new CountDownLatch(1);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
list2.add();
System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + "添加了一個(gè)元素..");
Thread.sleep(500);
if (list2.size() == 5) {
System.out.println("已經(jīng)發(fā)出通知..");
countDownLatch.countDown();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
if (list2.size() != 5) {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + "收到通知,線程停止..");
throw new RuntimeException();
}
}, "t2");
t2.start();
t1.start();
}
}