线程通讯
Posted 優syousetu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程通讯相关的知识,希望对你有一定的参考价值。
线程通讯:一个线程完成了自己的任务时,要通知另外一个线程去完成另外一个任务
生产者与消费者
通过产品建立关系
问题1:出现了线程安全问题。价格错乱。。(生产者的线程休眠10毫秒)
代码:
1 package com.java.test; 2 3 //产品 4 class product { 5 public String name; 6 public double price; 7 } 8 9 // 生产者 10 class producer extends Thread { 11 12 public product p; 13 14 public producer(product p) { 15 this.p = p; 16 } 17 18 @Override 19 public void run() { 20 int i = 1; 21 while (true) { 22 synchronized ("生产者") { 23 if (i % 2 == 0) { 24 p.name = "苹果"; 25 try { 26 Thread.sleep(10); 27 } catch (InterruptedException e) { 28 // TODO Auto-generated catch block 29 e.printStackTrace(); 30 } 31 p.price=6.5; 32 } else { 33 p.name="香蕉"; 34 p.price=2.0; 35 } 36 System.out.println("生产者生产出了:"+p.name+"价格:"+p.price); 37 i++; 38 } 39 40 } 41 } 42 } 43 44 // 消费者 45 class custom extends Thread { 46 public product p; 47 48 public custom(product p) { 49 this.p = p; 50 } 51 52 @Override 53 public void run() { 54 int i = 1; 55 while (true) { 56 synchronized ("消费者") { 57 System.out.println("消费者消费了:"+p.name+"价格为:"+p.price); 58 59 } 60 61 } 62 } 63 64 } 65 66 public class producer_custom { 67 68 public static void main(String[] args) { 69 70 product p = new product(); 71 producer pr= new producer(p); 72 custom c= new custom(p); 73 74 pr.start(); 75 c.start(); 76 77 78 79 } 80 81 }
将上述对象改为 产品 则上述问题改变
需求,生产一个,消费一个
wait(): 等待 如果线程执行了wait方法,那么该线程会进入等待的状态,等待状态下的线程,必须要被其他人调用notify()方法唤醒
notify(): 唤醒 唤醒等待的线程
wait与notify方法要注意的事项:
1.wait与notify方法是属于object对象的
2.wait与notify方法必须要在同步代码块或者是同步函数中才能使用
3.wait与notify方法必须由锁对象调用,
1 package com.java.test; 2 3 //产品 4 class product { 5 public String name; 6 public double price; 7 boolean flag = false; // 标识 表示产品是否被生产 8 } 9 10 // 生产者 11 class producer extends Thread { 12 13 public product p; 14 15 public producer(product p) { 16 this.p = p; 17 } 18 19 @Override 20 public void run() { 21 int i = 1; 22 while (true) { 23 synchronized (p) { 24 25 if (p.flag == false) { 26 if (i % 2 == 0) { 27 p.name = "苹果"; 28 p.price = 6.5; 29 30 } else { 31 p.name = "香蕉"; 32 p.price = 2.0; 33 34 } 35 i++; 36 p.flag = true; 37 } else { 38 try { 39 40 System.out.println("生产者生产出了:" + p.name + "价格:" + p.price); 41 p.wait(); 42 43 } catch (InterruptedException e) { 44 e.printStackTrace(); 45 } 46 } 47 48 } 49 50 } 51 } 52 } 53 54 // 消费者 55 class custom extends Thread { 56 public product p; 57 58 public custom(product p) { 59 this.p = p; 60 } 61 62 @Override 63 public void run() { 64 int i = 1; 65 while (true) { 66 synchronized (p) { 67 if (p.flag == true) { 68 System.out.println("消费者消费了:" + p.name + "价格为:" + p.price); 69 p.flag = false; 70 } else { 71 //产品还没有生产 72 p.notify(); 73 } 74 75 } 76 77 } 78 } 79 80 } 81 82 public class producer_custom { 83 84 public static void main(String[] args) { 85 86 product p = new product(); 87 producer pr = new producer(p); 88 custom c = new custom(p); 89 90 pr.start(); 91 c.start(); 92 93 } 94 95 }
守护线程(后台线程):如果一个进程中只剩下了守护线程,那么守护线程也会死亡
一个线程默认都不是守护线程
1 package com.java.test; 2 3 4 class test_daemon extends Thread{ 5 6 public test_daemon(String name){ 7 super(name); 8 } 9 10 @Override 11 public void run() { 12 for (int i = 0; i <= 100; i++) { 13 System.out.println("正在下载更新包"+"%"+i+"%"); 14 try { 15 Thread.sleep(10); 16 } catch (InterruptedException e) { 17 // TODO Auto-generated catch block 18 e.printStackTrace(); 19 } 20 if(i==100){ 21 System.out.println("下载完成,准备安装。。。"); 22 } 23 } 24 25 26 } 27 } 28 29 30 31 public class daemon { 32 public static void main(String[] args) { 33 test_daemon t_d = new test_daemon("后台线程"); 34 t_d.setDaemon(true); 35 t_d.start(); 36 37 for (int i = 0; i <=100; i++) { 38 System.out.println(Thread.currentThread().getName()+":"+i); 39 } 40 41 } 42 }
join方法:加入
一个线程,如果执行了join语句,那么就是有新的线程加入,执行该语句的线程必须要让步给新加入的线程完成任务,然后下能继续执行。
1 package com.java.test; 2 3 class Man extends Thread{ 4 @Override 5 public void run() { 6 System.out.println("他追她"); 7 System.out.println("追到了"); 8 System.out.println("甜蜜中。。。"); 9 System.out.println("男方出轨了。。。。"); 10 System.out.println("女方开始挽留男方"); 11 12 Woman w = new Woman(); 13 w.start(); 14 15 try { 16 w.join(); 17 } catch (InterruptedException e) { 18 // TODO Auto-generated catch block 19 e.printStackTrace(); 20 } 21 22 23 System.out.println("故事到这里就结束了"); 24 25 } 26 } 27 28 29 class Woman extends Thread{ 30 @Override 31 public void run() { 32 System.out.println("你这个渣男"); 33 System.out.println("终于看清你的面目了"); 34 System.out.println("分!!!"); 35 36 } 37 } 38 39 40 41 public class test_join { 42 public static void main(String[] args) { 43 Man m = new Man(); 44 m.start(); 45 } 46 }
以上是关于线程通讯的主要内容,如果未能解决你的问题,请参考以下文章
newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段