多线程之间通信的七种方式

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

猜你喜欢

转载自blog.csdn.net/qq_37685457/article/details/89738269