【Java笔记】6-三个线程交替打印数字(生产者消费者Plus版)
生产者消费者问题是老生常谈的问题,考察线程的同步等知识
Java中用于实现生产者消费者主要使用synchronized、对象.wait()、对象.notify()来实现
前置知识
synchronized
该字段可对方法使用、可对代码片使用,用于控制线程互斥
wait()
用于通知掌握该对象锁的线程等待通知
notify()
用于通知等待对象锁的线程开始运行
生产者消费者
其中list是生产者消费者共享的资源
每次该共享资源被释放(生产完或消费完),生产者消费者都有可能进入临界区,但无所谓,不满足条件的会卡住,让另一个执行
public class ProduceConsume {
public static void main(String[] args) {
List list =new ArrayList();
Producer p=new Producer(list);
Consumer c=new Consumer(list);
new Thread(p,"生产者").start();
new Thread(c,"消费者").start();
}
}
class Producer implements Runnable {
private List list;
public Producer(List list) {
this.list = list;
}
public void run(){
while(true){
synchronized (list) {//synchronized控制不同线程同步
if (list.size()>0){
//如果发现不能生产 就调用wait(),释放锁
try {
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else{
//否则就生产一个,并通知消费者可以来拿
//就算下次又是生产者进来,那无所谓,会进入wait
produce();
list.notifyAll();
}
}
}
}
public void produce(){
list.add(new Object());//加到后面
System.out.println(Thread.currentThread().getName()+"生产产品");
}
}
class Consumer implements Runnable {
private List list;
public Consumer(List list) {
this.list = list;
}
public void run(){
while (true){
synchronized (list) {
if (list.size()==0){
try {
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else{
consume();
list.notifyAll();
}
}
}
}
public void consume(){
list.remove(0);
System.out.println(Thread.currentThread().getName()+"消费产品");
}
}
三个线程交替打印数字
这里思想非常简单,在生产者消费者的基础上,有以下变化:
- 共享资源变成三个,两两使用一个控制同步
- 每个线程消费后再生产,这样下一个线程可以消费再生产
- 两层synchronized嵌套,第一层控制消费,第二层控制生产
- main函数里初始化往第一个共享资源生产一下,使得整体开始运行
- 三个线程共享代码段,只是传入的参数不同
import java.util.ArrayList;
import java.util.List;
public class PrintInTurn {
public static void main(String[] args) {
List list1 = new ArrayList();
List list2 = new ArrayList();
List list3 = new ArrayList();
list1.add(new Object());
ProducerConsumer p1=new ProducerConsumer(list1,list2);
ProducerConsumer p2=new ProducerConsumer(list2,list3);
ProducerConsumer p3=new ProducerConsumer(list3,list1);
new Thread(p1,"p1").start();
new Thread(p2,"p2").start();
new Thread(p3,"p3").start();
}
}
class ProducerConsumer implements Runnable {
private List list1,list2;
public ProducerConsumer(List list1, List list2) {
this.list1 = list1;
this.list2 = list2;
}
public void run(){
//int i=0;//控制生产个数
while(true){
//if (i>2){//控制生产个数
// break;
//}
synchronized (list1) {
if (list1.size()==0){
//线程进入等待
try {
list1.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else{
consume(list1);
//i++;//控制生产个数
list1.notifyAll();
synchronized (list2) {
if (list2.size()==1){
try {
list2.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else{
produce(list2);
list2.notifyAll();
}
}
}
}
}
}
public void produce(List lis){
lis.add(new Object());//加到后面
System.out.println(Thread.currentThread().getName()+"生产产品");
}
public void consume(List lis){
lis.remove(0);
// System.out.println(Thread.currentThread().getName()+"消费产品");
}
}
原文地址:https://blog.csdn.net/weixin_43735161/article/details/143490320
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!