java多线程协作
创始人
2025-05-30 15:51:34

Java提供了几个方法解决线程之间的通信问题

  • wait():表示线程一直等待,直到其他线程通知,与sleep不同,会释放锁
  • wait(long timeout):指定等待的毫秒数
  • notify():唤醒一个处于等待状态的线程
  • notifyAll():唤醒同一个对象上所有调用wait(方法的线程,优先级别高的线程优先调度
  • 注意:均是Onject类的方法,都只能在同步方法或同步代码块中使用,否则会抛出illegalMonitorStateException

并发协作模型"生产者/消费者模式"---------->管程法

  • 生产者:负责生产数据的模块(可能是方法,对象,线程,进程)
  • 消费者:负责处理数据的模块(可能是方法,对象,线程,进程)
  • 缓冲区:消费者不能直接使用生产者的数据,他们之间有个“缓冲区”
package com.ou.p3;//测试:生产者消费者模型----》管程法 利用缓冲区解决
//生产者 消费者 产品 缓冲区
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 synContainer;public Productor(SynContainer synContainer){this.synContainer = synContainer;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {synContainer.push(new Chicken(i));System.out.println("生产了第"+i+"只鸡");}}
}//消费者
class Consumer extends Thread{SynContainer synContainer;public Consumer(SynContainer synContainer){this.synContainer = synContainer;}@Overridepublic void run() {for (int i = 0; i < 100; i++) {Chicken chicken =  synContainer.pop();System.out.println("消费了第"+chicken.id+"只鸡");}}
}//产品
class Chicken{int id;//产品编号public Chicken(int id){this.id = id;}
}//缓冲区
class SynContainer{//需要一个容器大小Chicken[] chickens = new Chicken[10];//容器计数器int count;//生产者放入一个产品public synchronized void push(Chicken chicken){//如果容器满了,就要等待消费者消费if(chickens.length == count){//等待消费者消费try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//如果没有满,我们就需要丢入产品chickens[count] = chicken;count++;//通知消费者消费this.notifyAll();}//消费者消费产品public synchronized Chicken pop(){//判断能否消费if(count == 0){//消费者等待try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}count--;Chicken chicken = chickens[count];//通知生产者生产this.notifyAll();return chicken;}
}

并发协作模型“生产者/消费者模式”----->信号灯法

package com.ou.p3;
//测试生产者消费者问题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 = new TV();public Player(TV tv) {this.tv = tv;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {if(i%2==0){try {tv.play("快乐大本营");} catch (InterruptedException e) {e.printStackTrace();}}else {try {tv.play("抖音");} catch (InterruptedException e) {e.printStackTrace();}}}}
}//消费者----》观众
class Watcher extends Thread{TV tv = new TV();public Watcher(TV tv) {this.tv = tv;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {tv.watch();}}
}//产品---》节目
class TV{//演员表演 观众等待 T//观众观看 演员等待 FString voice;//表演节目boolean flag = true;//标志位//表演public synchronized void play(String voice) throws InterruptedException {if(!flag){this.wait();}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;}}

线程池

  • 背景:经常创建和销毁、使用特别大的资源,比如并发情况下对的线程,对性能影响很大。
  • 思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建和销毁、实现重复利用。类似生活中的公共交通工具。
package com.ou.p3;import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TestPool {public static void main(String[] args) {//创建服务 创建线程池//newFixedThreadPool 参数为线程池容量ExecutorService service= Executors.newFixedThreadPool(10);service.execute(new MyThread());}}class MyThread implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}
}

相关内容

热门资讯

今日重大通报“新猴王大厅透视软... 您好:新猴王大厅这款游戏可以开挂,确实是有挂的,需要软件加微信【4770480】,很多玩家在新猴王大...
玩家必看“圣盛棋牌究竟有挂吗”... 亲.圣盛棋牌这款游戏是可以开挂的,确实是有挂的,通过添加客服【3671900】很多玩家在这款游戏中怀...
实测分享.“[心悦龙江麻将]究... 亲,心悦龙江麻将这款游戏可以开挂的,确实是有挂的,添加客服微信【7482525】安装软件,很多玩家在...
玩家实测“新九哥大厅到底有没有... 您好:新九哥大厅这款游戏可以开挂,确实是有挂的,需要软件加微信【5951795】,很多玩家在新九哥大...
玩家必看“微信链接拼十有没有透... 您好:微信链接拼十这款游戏可以开挂,确实是有挂的,需要软件加微信【4770480】,很多玩家在微信链...