当前位置: 首页 > news >正文

多线程(续)

多线程(续)

1.死锁

package com.tian.thread;//死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class DeadLock {public static void main(String[] args) {Makeup g1 = new Makeup(0,"灰姑娘");Makeup g2 = new Makeup(1,"白雪公主");g1.start();g2.start();}
}//口红
class Lipstick{}//镜子
class Mirror{}class Makeup extends Thread{static Lipstick lipstick = new Lipstick();static Mirror mirror = new Mirror();int choice;//选择String girlName;//使用化妆品的人Makeup(int choice , String girlName){this.choice =choice;this.girlName = girlName;}@Overridepublic void run() {//化妆try {makeup();} catch (InterruptedException e) {e.printStackTrace();}}//化妆,互相持有对方的债,就是需要拿到对方的资源private void makeup() throws InterruptedException {if (choice==0){synchronized (lipstick){//获得口红的债System.out.println(this.girlName+"获得口红的锁");Thread.sleep(1000);synchronized (mirror) {//一秒钟后获得镜子System.out.println(this.girlName+"获得镜子的锁");}}}else {synchronized (mirror){//获得镜子的债System.out.println(this.girlName+"获得镜子的锁");Thread.sleep(2000);synchronized (lipstick) {//二秒钟后获得口红System.out.println(this.girlName+"获得口红的锁");}}}}
}

解决方法:

package com.tian.thread;//死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class DeadLock {public static void main(String[] args) {Makeup g1 = new Makeup(0,"灰姑娘");Makeup g2 = new Makeup(1,"白雪公主");g1.start();g2.start();}
}//口红
class Lipstick{}//镜子
class Mirror{}class Makeup extends Thread{static Lipstick lipstick = new Lipstick();static Mirror mirror = new Mirror();int choice;//选择String girlName;//使用化妆品的人Makeup(int choice , String girlName){this.choice =choice;this.girlName = girlName;}@Overridepublic void run() {//化妆try {makeup();} catch (InterruptedException e) {e.printStackTrace();}}//化妆,互相持有对方的债,就是需要拿到对方的资源private void makeup() throws InterruptedException {if (choice==0){synchronized (lipstick){//获得口红的债System.out.println(this.girlName+"获得口红的锁");Thread.sleep(1000);}synchronized (mirror) {//一秒钟后获得镜子System.out.println(this.girlName+"获得镜子的锁");}}else {synchronized (mirror){//获得镜子的债System.out.println(this.girlName+"获得镜子的锁");Thread.sleep(2000);}synchronized (lipstick) {//二秒钟后获得口红System.out.println(this.girlName+"获得口红的锁");}}}
}

产生死锁的四个必要条件:

  • 互斥条件:一个资源每次只能被一个进程使用
  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
  • 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

2.Lock锁

package com.tian.gaoji;import java.util.concurrent.locks.ReentrantLock;//测试Lock锁
public class TestLock {public static void main(String[] args) {TestLock2 testLock2 = new TestLock2();new Thread(testLock2).start();new Thread(testLock2).start();new Thread(testLock2).start();}
}class TestLock2 implements Runnable{int ticketNums = 10;//定义Lock锁ReentrantLock lock = new ReentrantLock();@Overridepublic void run() {while (true){try{lock.lock();//加锁if (ticketNums>0){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(ticketNums--);}else {break;}}finally {//解锁lock.unlock();}}}
}

3.生产者消费问题

3.1管程法

package com.tian.gaoji;//测试生产者消费者模型-->利用缓冲区解决:管程法//生产者;消费者;产品;缓冲区
public class TestPC {public static void main(String[] args) {SynContainer container = new SynContainer();new Productor(container).start();new Consumer(container).start();}
}//生产者
class Productor extends Thread{SynContainer container;public Productor(SynContainer container){this.container =container;}//生产@Overridepublic void run() {for (int i = 0; i < 100; i++) {container.push(new Chicken(i));System.out.println("生产了"+i+"只鸡");}}
}//消费者
class  Consumer extends Thread{SynContainer container;public Consumer(SynContainer container){this.container = container;}//消费@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("消费了-->"+container.pop().id+"只鸡");}}
}//产品
class  Chicken{int id;//产品编号public Chicken(int id){this.id = id;}
}//缓冲区
class SynContainer{//需要一个容器大小Chicken[] chickens = new Chicken[10];//容器计数器int count = 0;//生产者放入产品public synchronized void push(Chicken chicken){//如果容器满了,就需要等待消费者消费if (count==chickens.length){//通知消费者消费,生产等待}//如果没有满,我们就需要丢入产品chickens[count]=chicken;count++;//可以通知消费者消费了}//消费者消费产品public synchronized Chicken pop(){//判断能否消费if (count==0){//等待生产者生产,消费者等待}//如果可以消费count--;Chicken chicken = chickens[count];//吃完了,通知生产者生产return chicken;}
}

3.2信号灯法

package com.tian.gaoji;//测试生产者消费者问题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;}@Overridepublic void run() {for (int i = 0; i < 20; 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;}@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){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;}
}

4.线程池

package com.tian.gaoji;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{@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}
}

5.总结

package com.tian.gaoji;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;//回顾总结线程的创建
public class ThreadNew {public static void main(String[] args) {new MyThread1().start();new Thread(new MyThread2()).start();FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread3());new Thread(futureTask).start();try {Integer integer = futureTask.get();System.out.println(integer);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}
}
//1.继承Thread类
class MyThread1 extends Thread{@Overridepublic void run() {System.out.println("MyThread1");}
}
//2.实现Runnable接口
class MyThread2 implements Runnable{@Overridepublic void run() {System.out.println("MyThread2");}
}
//3.实现Callable接口
class MyThread3 implements Callable<Integer>{@Overridepublic Integer call() throws Exception {System.out.println("MyThread3");return 100;}
}
http://www.sczhlp.com/news/833.html

相关文章:

  • 2025 -- 云智计划 -- 【CSP-S】模拟赛 #1_总结+题解
  • 习题-有限集
  • 29
  • 第二十六天
  • 【题解】P12019 [NOISG 2025 Finals] 洪水
  • pygame小游戏打飞机_2模块显示
  • tt
  • 工程建立 - LI,Yi
  • Java基础语法学习 ———— Day1
  • 阶跃星辰端到端语音模型 Step-Audio 2:深度思考+音色切换;11Labs 对话式 AI 增加 WebRTC支持丨日报
  • 子串的故事(2) - 2025“钉耙编程”中国大学生算法设计暑期联赛(2)T4 题解
  • 【比赛记录】2025CSP-S模拟赛28
  • Apereo CAS 4.1 反序列化命令执行漏洞 (复现)
  • 第十四篇
  • 《大道至简——软件工程实践者的思想》读后感
  • DE_aemmprty 题单合集(分类)
  • 假期学习
  • C++对象模型
  • 软工7.28
  • P2910 [USACO08OPEN] Clear And Present Danger S (Floyd算法)
  • 读《构建之法》:我的C/C++学习反思
  • Qt播放音频,支持进度条,设置语速,播放暂停
  • goethereum-账户 - Charlie
  • 使用监督学习训练图像聚类模型
  • java第二十八天
  • 二叉树 (动态规划)
  • 1 引言(1.1 - 1.5)
  • 支持向量机算法
  • 决策树算法
  • 逻辑回归算法