首页 > 编程语言 > 详细

线程协作

时间:2021-05-12 14:36:46      阅读:7      评论:0      收藏:0      [点我收藏+]

线程协作

生产者消费者问题

管程法

  1. 生产者生成,消费者消费,缓冲区用于连接,让消费者不能直接接触生产者的数据

  2. 生产者将生产好的数据放入缓冲区。消费者去缓冲区拿出数据

package com.thread.syn;
?
//测试:生产者消费者问题-》利用缓冲区缓存---管程法
//需要生产者 消费者 产品 和缓冲区
public class TestPC {
   public static void main(String[] args) {
       SynContainer synContainer=new SynContainer();
       new Productor(synContainer).start();
       new Consumer(synContainer).start();
  }
}
//生产者
class Productor extends Thread{
   SynContainer container;
   public Productor(SynContainer container){
       this.container=container;
  }
?
   //生产
?
   @Override
   public void run() {
       for (int i = 0; i < 100; i++) {
           System.out.println("生产了"+i+"只鸡");
           container.push(new Dream(i));
      }
  }
}
?
//消费者
class Consumer extends Thread{
   SynContainer container;
   public Consumer(SynContainer container){
       this.container=container;
  }
?
   //消费
?
   @Override
   public void run() {
       for (int i = 0; i < 100; i++) {
           System.out.println("消费了"+container.pop().id+"只鸡");
      }
  }
}
?
//产品
class Dream{
   int id;//产品编号
?
   public Dream(int id) {
       this.id = id;
  }
}
?
//缓冲区
class SynContainer{
?
   //需要一个容器大小
   Dream[] dreams=new Dream[10];
   //容器计数器
   int count=0;
?
   //需要生产者放入产品
   public synchronized void push(Dream dream){
       //如果容器满了,需要等待消费者消费
       while (count==dreams.length){
           //通知消费者消费,生产者等待
           try {
               this.wait();
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
      }
       //如果容器没满,需要生产者丢人产品
       dreams[count]=dream;
       count++;
?
       //可以通知消费者消费
       this.notifyAll();
?
  }
   //消费者消费产品
   public synchronized Dream pop(){
       //判断是否消费
       while (count==0){
           //等待生产者生成。
           try {
               this.wait();
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
      }
       //如果可以消费,就消费
       count--;
       Dream dream =dreams[count];
?
       //通知生产者生成
       this.notifyAll();
       return dream;
  }
?
}

信号灯管理法

设置一个标志位,通过改变标志位来通知、等待

package com.thread.syn;
?
//测试生产者消费者问题2---信号灯法,用标志位解决
public class TestPC2 {
   public static void main(String[] args) {
       TV tv=new TV();
       new Player(tv).start();
       new Watcher(tv).start();
  }
?
}
//生产者
class Player extends Thread{
   TV tv;
   public Player(TV tv){
       this.tv=tv;
  }
?
   @Override
   public void run() {
       for (int i = 0; i < 10; i++) {
           if (i%2==0){
               this.tv.play("动画");
          }else {
               this.tv.play("广告");
          }
      }
  }
}
?
//消费者
class Watcher extends Thread{
   TV tv;
   public Watcher(TV tv){
       this.tv=tv;
  }
?
   @Override
   public void run() {
       for (int i = 0; i < 10; i++) {
           tv.watch();
      }
  }
}
?
//产品
class TV{
   //演员表演,观众等待 T
   //观众观看,演员等待 F
   String voice;//表演姐夫
   boolean flag=true;
   //表演
   public synchronized void play(String voice){
       if (!flag){
           try {
               this.wait();
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
      }
       System.out.println("演员表演了-->"+voice);
       //通知观众观看
       this.notifyAll();//通知唤醒
       this.voice=voice;
       this.flag=!this.flag;
  }
?
   //观看
   public synchronized void watch(){
       if (flag){
           try {
               this.wait();
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
      }
       System.out.println("观众观看了->"+voice);
?
       //通知演员表演
       this.notifyAll();
       this.flag=!this.flag;
?
  }
}

线程池

  1. 线程池相关的API:ExecutorService和Executors

  2. ExecutorService是真正的线程池接口需要通过Executors来创建一个池子的大小

  3. 执行的时候是通过execute来执行Runnable(void execute(Runnable command)),一般没有返回值,用shutdown()来关闭

package com.thread.syn;
?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
?
public class TestPool {
   public static void main(String[] args) {
       //1.创建服务,创建线程池
       //newFixedThreadPool 参数为:线程池大小
       ExecutorService service= Executors.newFixedThreadPool(10);
?
       //执行
       service.execute(new MyThread());
       service.execute(new MyThread());
       service.execute(new MyThread());
       service.execute(new MyThread());
?
       //2.关闭连接
       service.shutdown();
  }
   
}
class MyThread implements Runnable{
?
   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
  }
}

 

线程协作

原文:https://www.cnblogs.com/Share-my-life/p/14759217.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!