1、synchronized + wait + notifyAll + 条件
2、Lock + Condition + 条件
3、Semaphore
4、CountDownLatch
5、Cyclicbarrier
6、Exchanger
7、sleep、join、yeild
以下是案例:
线程通信一 之:synchronized + wait + notifyAll + 条件
(模拟生产者消费者)
仓库类:
package cn.skq.wait;
/**
* 仓库类
* @author Administrator
*
*/
public class Tianmao {
private volatile int value;
private final int MAX_VALUE = 10;
private final int MIN_VALUE = 0;
public synchronized void shengChan() {
while (value >= MAX_VALUE) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ " :停止生产,当前库存:" + value);
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
value++;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :正在生产,库存:"
+ value);
this.notifyAll();
}
public synchronized void xiaoFei() {
while (value <= MIN_VALUE) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ " :停止消费,当前库存:" + value);
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
value--;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :正在消费,库存:"
+ value);
this.notifyAll();
}
}
生产任务类:
package cn.skq.wait;
public class ShengChanTrag implements Runnable{
private Tianmao t;
public ShengChanTrag(Tianmao t) {
super();
this.t = t;
}
@Override
public void run() {
while(true){
t.shengChan();
}
}
}
消费任务类:
package cn.skq.wait;
public class XiaoFeiTrag implements Runnable{
private Tianmao t;
public XiaoFeiTrag(Tianmao t) {
super();
this.t = t;
}
@Override
public void run() {
while(true){
t.xiaoFei();
}
}
}
测试类:
package cn.skq.wait;
/**
* 线程通信一 之
* synchronized + wait + notifyAll + 条件
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
Tianmao t = new Tianmao();
new Thread(new ShengChanTrag(t)).start();
new Thread(new ShengChanTrag(t)).start();
new Thread(new ShengChanTrag(t)).start();
new Thread(new XiaoFeiTrag(t)).start();
new Thread(new XiaoFeiTrag(t)).start();
new Thread(new XiaoFeiTrag(t)).start();
new Thread(new XiaoFeiTrag(t)).start();
}
}
结果:
Thread-0 :正在生产,库存:1
Thread-0 :正在生产,库存:2
Thread-6 :正在消费,库存:1
Thread-6 :正在消费,库存:0
Thread-5 :停止消费,当前库存:0
Thread-4 :停止消费,当前库存:0
Thread-3 :停止消费,当前库存:0
Thread-2 :正在生产,库存:1
Thread-1 :正在生产,库存:2
Thread-1 :正在生产,库存:3
Thread-1 :正在生产,库存:4
Thread-1 :正在生产,库存:5
Thread-2 :正在生产,库存:6
Thread-2 :正在生产,库存:7
Thread-3 :正在消费,库存:6
线程通信二 之:Lock + Condition + 条件
(模拟生产者消费者)
仓库类:
package cn.skq.condition;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 仓库类
*
* @author Administrator
*
*/
public class Tianmao {
private volatile int value;
private final int MAX_VALUE = 10;
private final int MIN_VALUE = 0;
private Lock lock = new ReentrantLock();
Condition c1 = lock.newCondition();
Condition c2 = lock.newCondition();
public void shengChan() {
lock.lock();
while (value >= MAX_VALUE) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ " :停止生产,当前库存:" + value);
try {
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
value++;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :正在生产,库存:"
+ value);
c2.signalAll();
lock.unlock();
}
public void xiaoFei() {
lock.lock();
while (value <= MIN_VALUE) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ " :停止消费,当前库存:" + value);
try {
c2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
value--;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :正在消费,库存:"
+ value);
c1.signalAll();
lock.unlock();
}
}
生产任务:
package cn.skq.condition;
public class ShengChanTrag implements Runnable{
private Tianmao t;
public ShengChanTrag(Tianmao t) {
super();
this.t = t;
}
@Override
public void run() {
while(true){
t.shengChan();
}
}
}
消费任务:
package cn.skq.condition;
public class XiaoFeiTrag implements Runnable{
private Tianmao t;
public XiaoFeiTrag(Tianmao t) {
super();
this.t = t;
}
@Override
public void run() {
while(true){
t.xiaoFei();
}
}
}
测试类:
package cn.skq.condition;
/**
* 线程通信二 之:
* Lock + Condition + 条件
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
Tianmao t = new Tianmao();
new Thread(new ShengChanTrag(t)).start();
new Thread(new ShengChanTrag(t)).start();
new Thread(new ShengChanTrag(t)).start();
new Thread(new XiaoFeiTrag(t)).start();
new Thread(new XiaoFeiTrag(t)).start();
new Thread(new XiaoFeiTrag(t)).start();
new Thread(new XiaoFeiTrag(t)).start();
}
}
测试结果:
Thread-0 :正在生产,库存:1
Thread-1 :正在生产,库存:2
Thread-2 :正在生产,库存:3
Thread-2 :正在生产,库存:4
Thread-2 :正在生产,库存:5
Thread-3 :正在消费,库存:4
Thread-3 :正在消费,库存:3
Thread-4 :正在消费,库存:2
Thread-4 :正在消费,库存:1
Thread-5 :正在消费,库存:0
Thread-6 :停止消费,当前库存:0
Thread-0 :正在生产,库存:1
Thread-1 :正在生产,库存:2
Thread-2 :正在生产,库存:3
Thread-2 :正在生产,库存:4
Thread-2 :正在生产,库存:5
线程通信三 之: Semaphore
(模拟排队去厕所,厕所的位置是有限的)
厕所类:
package cn.skq.semaphore;
import java.util.concurrent.Semaphore;
public class Wc {
private Semaphore semaphore = new Semaphore(3);
public void paidui() {
try {
semaphore.acquire();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :正在使用厕所");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :使用厕所完毕");
semaphore.release();
}
}
任务类:
package cn.skq.semaphore;
public class WcTrag implements Runnable{
private Wc wc;
public WcTrag(Wc wc) {
super();
this.wc = wc;
}
@Override
public void run() {
wc.paidui();
}
}
测试类:
package cn.skq.semaphore;
/**
* 线程通信三 之:
* Semaphore
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
Wc wc = new Wc();
for (int i = 0; i < 50; i++) {
new Thread(new WcTrag(wc)).start();
}
}
}
结果:
Thread-0 :正在使用厕所
Thread-3 :正在使用厕所
Thread-4 :正在使用厕所
Thread-0 :使用厕所完毕
Thread-16 :正在使用厕所
Thread-3 :使用厕所完毕
Thread-15 :正在使用厕所
Thread-4 :使用厕所完毕
Thread-12 :正在使用厕所
Thread-16 :使用厕所完毕
Thread-11 :正在使用厕所
Thread-15 :使用厕所完毕
Thread-8 :正在使用厕所
Thread-12 :使用厕所完毕
Thread-7 :正在使用厕所
线程通信四 之:CountDownLatch
(模拟吃饭,主线程在其他线程执行之后在吃饭)
吃饭类:
package cn.skq.countdownlatch;
import java.util.concurrent.CountDownLatch;
public class Eat {
private CountDownLatch countDownLatch;
public Eat(CountDownLatch countDownLatch) {
super();
this.countDownLatch = countDownLatch;
}
public void eatting() {
System.out.println(Thread.currentThread().getName() + " :正在吃饭");try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
}
任务类:
package cn.skq.countdownlatch;
public class EatTrag implements Runnable{
private Eat eat;
public EatTrag(Eat eat) {
super();
this.eat = eat;
}
@Override
public void run() {
eat.eatting();
}
}
测试类:
package cn.skq.countdownlatch;
import java.util.concurrent.CountDownLatch;
/**
* 线程通信四 之:
* CountDownLatch
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(10);
Eat eat = new Eat(countDownLatch);
for (int i = 0; i < 10; i++) {
new Thread(new EatTrag(eat)).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("都吃完了,主线程开始吃饭");
}
}
结果:
Thread-1 :正在吃饭
Thread-0 :正在吃饭
Thread-3 :正在吃饭
Thread-2 :正在吃饭
Thread-7 :正在吃饭
Thread-5 :正在吃饭
Thread-4 :正在吃饭
Thread-8 :正在吃饭
Thread-9 :正在吃饭
Thread-6 :正在吃饭
都吃完了,主线程开始吃饭
线程通信五 之:Cyclicbarrier
(模拟开会,所有人到达之后才一起开会)
开会类:
package cn.skq.cyclicbarrier;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Meet {
private CyclicBarrier barrier;
private Random random = new Random();
public Meet(CyclicBarrier barrier) {
super();
this.barrier = barrier;
}
public void meeting() {
System.out.println(Thread.currentThread().getName() + " :正在赶来的路上");
try {
Thread.sleep(random.nextInt(10000));
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :已经来到会议室");
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
任务类:
package cn.skq.cyclicbarrier;
public class MeetTrag implements Runnable{
private Meet meet;
public MeetTrag(Meet meet) {
super();
this.meet = meet;
}
@Override
public void run() {
meet.meeting();
}
}
测试类:
package cn.skq.cyclicbarrier;
import java.util.concurrent.CyclicBarrier;
/**
* 线程通信五 之:
* Cyclicbarrier
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(10, new Runnable() {
@Override
public void run() {
System.out.println("人来齐了,开始开会");
}
});
Meet meet = new Meet(barrier);
for (int i = 0; i < 10; i++) {
new Thread(new MeetTrag(meet)).start();
}
}
}
结果:
Thread-0 :正在赶来的路上
Thread-4 :正在赶来的路上
Thread-3 :正在赶来的路上
Thread-2 :正在赶来的路上
Thread-1 :正在赶来的路上
Thread-0 :已经来到会议室
Thread-4 :已经来到会议室
Thread-3 :已经来到会议室
Thread-2 :已经来到会议室
Thread-1 :已经来到会议室
人来齐了,开始开会
线程通信六 之:Exchanger
(模拟两台数据挖掘机器,挖掘之后将两个线程的挖掘的数据交换)
数据挖掘类:
package cn.skq.exchanger;
import java.util.concurrent.Exchanger;
public class Shuju {
private Exchanger<String> exchanger;
public Shuju(Exchanger<String> exchanger) {
super();
this.exchanger = exchanger;
}
public void wajueA() {
String str = "aaa";
System.out.println(Thread.currentThread().getName() + " :开始挖掘数据");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :挖掘数据完毕,数据为:"
+ str);
try {
String ss = exchanger.exchange(str);
System.out.println(Thread.currentThread().getName() + " :交换后得到数据,数据为:"
+ ss);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void wajueB() {
String str = "bbb";
System.out.println(Thread.currentThread().getName() + " :开始挖掘数据");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :挖掘数据完毕,数据为:"
+ str);
try {
String ss = exchanger.exchange(str);
System.out.println(Thread.currentThread().getName() + " :交换后得到数据,数据为:"
+ ss);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
任务A:
package cn.skq.exchanger;
public class ShujuTragA implements Runnable {
private Shuju shuju;
public ShujuTragA(Shuju shuju) {
super();
this.shuju = shuju;
}
@Override
public void run() {
shuju.wajueA();
}
}
任务B:
package cn.skq.exchanger;
public class ShujuTragB implements Runnable {
private Shuju shuju;
public ShujuTragB(Shuju shuju) {
super();
this.shuju = shuju;
}
@Override
public void run() {
shuju.wajueB();
}
}
测试类:
package cn.skq.exchanger;
import java.util.concurrent.Exchanger;
/**
* 线程通信六 之:
* Exchanger
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
Shuju shuju = new Shuju(exchanger);
new Thread(new ShujuTragA(shuju)).start();
new Thread(new ShujuTragB(shuju)).start();
}
}
结果
Thread-0 :开始挖掘数据
Thread-1 :开始挖掘数据
Thread-0 :挖掘数据完毕,数据为:aaa
Thread-1 :挖掘数据完毕,数据为:bbb
Thread-0 :交换后得到数据,数据为:bbb
Thread-1 :交换后得到数据,数据为:aaa
线程通信 七 之: sleep或join 或 yelid
测试join()类:
package cn.skq.joinandyeild;
/**
* 线程通信 七 之:
* join 或 yelid
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是一个快乐的小线程2");
}
});
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是一个悲伤的小线程1");
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是一个愤怒的小线程3");
}
});
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t3.start();
}
}
结果:
我是一个悲伤的小线程1
我是一个快乐的小线程2
我是一个愤怒的小线程3