线程间通信其实就是多个线程在操作同一个资源时,多个线程之间不断切换执行时所发出的信号。例如:需要创建两个线程,一条线程只打印1-26的数字,另一条只打印A-Z的字母,最终打印结果为1A2B3C4D…26Z时,这时就需要使用线程之间的通信来交替完成。
首先创建一个共用的线程池去管理和运行这两个线程:
public class ThreadPoolTest {
// 创建一个定长的线程池
private static final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
// 创建一个数字的数组
public static String[] buildNoArr(int max) {
String[] noArr = new String[max];
for(int i=0;i
public class ThreadTest1 {
// 创建线程池对象
ThreadPoolTest poolTest = new ThreadPoolTest();
// 创建一个空的集合对象用来存放打印的字符,并用该对象生成一个对象锁
private final List list = new ArrayList<>();
public Runnable newThreadOne() {
final String[] noArr = poolTest.buildNoArr(26);
return new Runnable() {
public void run() {
for (int i = 0; i < noArr.length; i++) {
synchronized (list) {
if (list.size() % 2 == 1) {
try {
list.wait(); //调用该锁对象的wait()方法,使当前线程进入等待状态,该线程后面的逻辑暂停执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
poolTest.printStr(noArr[i]);
list.add(noArr[i]);
list.notify(); //调用该锁对象的notify()方法,此时会唤醒newThreadTwo线程,使newThreadTwo线程进入就绪状态,当newThreadTwo重新获取到cup时,则继续从上次暂停的代码处往下执行
}
}
}
};
}
public Runnable newThreadTwo() {
final String[] charArr = poolTest.buildCharArr(26);
return new Runnable() {
public void run() {
for (int i = 0; i < charArr.length; i++) {
synchronized (list) {
if (list.size() % 2 == 0) {
try {
list.wait(); //调用该锁对象的wait()方法,使当前线程进入等待状态,该线程后面的逻辑暂停执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
poolTest.printStr(charArr[i]);
list.add(charArr[i]);
list.notify();//调用该锁对象的notify()方法,此时会唤醒newThreadOne线程,使newThreadOne线程进入就绪状态,当newThreadOne重新获取到cup时,则继续从上次暂停的代码处往下执行
}
}
}
};
}
// 测试
public static void main(String args[]) {
ThreadTest1 three = new ThreadTest1();
ThreadPoolTest poolTest = new ThreadPoolTest();
poolTest.run(three.newThreadOne());
poolTest.run(three.newThreadTwo());
poolTest.shutdown();
}
}
public class ThreadTest2 {
static volatile int value = 1;
int one = 0;
int two = 0;
ThreadPoolTest poolTest = new ThreadPoolTest();
public Runnable newThreadOne() {
final String[] noArr = poolTest.buildNoArr(26);
return new Runnable() {
public void run() {
while (true) {
if (value == 1 && one < noArr.length) {
poolTest.printStr(noArr[one]);
one++;
value = 2;
}
}
}
};
}
public Runnable newThreadTwo() {
final String[] charArr = poolTest.buildCharArr(26);
return new Runnable() {
public void run() {
while (true) {
if (value == 2 && two < charArr.length) {
poolTest.printStr(charArr[two]);
two++;
value = 1;
}
}
}
};
}
public static void main(String args[]) {
ThreadTest2 three = new ThreadTest2();
ThreadPoolTest poolTest = new ThreadPoolTest();
poolTest.run(three.newThreadOne());
poolTest.run(three.newThreadTwo());
poolTest.shutdown();
}
}
public class ThreadTest3 {
private static volatile int value = 1;
private Lock lock = new ReentrantLock(true);
private Condition condition = lock.newCondition();
ThreadPoolTest poolTest = new ThreadPoolTest();
public Runnable newThreadOne() {
final String[] noArr = poolTest.buildNoArr(26);
return new Runnable() {
public void run() {
for (int i = 0; i < noArr.length; i++) {
try {
lock.lock(); //newThreadOne线程获取锁
if (value == 2) {
condition.await(); // newThreadOne线程进入等待阻塞
}
poolTest.printStr(noArr[i]);
value = 2;
condition.signal(); // 唤醒调用condition.await()进入阻塞的线程
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock(); // 手动释放锁
}
}
}
};
}
public Runnable newThreadTwo() {
final String[] charArr = poolTest.buildCharArr(26);
return new Runnable() {
public void run() {
for (int i = 0; i < charArr.length; i++) {
try {
lock.lock(); // newThreadTwo线程获取锁
if (value == 1) {
condition.await(); // newThreadTwo线程进入等待阻塞
}
poolTest.printStr(charArr[i]);
value = 1;
condition.signal(); // 唤醒调用condition.await()进入阻塞的线程
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock(); // 手动释放锁
}
}
}
};
}
public static void main(String args[]) {
ThreadTest3 three = new ThreadTest3();
ThreadPoolTest poolTest = new ThreadPoolTest();
poolTest.run(three.newThreadOne());
poolTest.run(three.newThreadTwo());
poolTest.shutdown();
}
}
public class ThreadTest4 {
private AtomicInteger value = new AtomicInteger(1);
int one = 0;
int two = 0;
ThreadPoolTest poolTest = new ThreadPoolTest();
public Runnable newThreadOne() {
final String[] noArr = poolTest.buildNoArr(26);
return new Runnable() {
public void run() {
while (true) {
if (value.get() == 1 && one < noArr.length) {
poolTest.printStr(noArr[one]);
one++;
value.set(2);
}
}
}
};
}
public Runnable newThreadTwo() {
final String[] charArr = poolTest.buildCharArr(26);
return new Runnable() {
public void run() {
while (true) {
if (value.get() == 2 && two < charArr.length) {
poolTest.printStr(charArr[two]);
two++;
value.set(1);
}
}
}
};
}
public static void main(String args[]) {
ThreadTest4 three = new ThreadTest4();
ThreadPoolTest poolTest = new ThreadPoolTest();
poolTest.run(three.newThreadOne());
poolTest.run(three.newThreadTwo());
poolTest.shutdown();
}
}