Java中线程的通信
来源:互联网 发布:离线整个知乎 编辑:程序博客网 时间:2024/06/14 01:23
1.线程的协调运行
以借助于Object类提供的wait()、notify()和notifyAll()三个方法,这三个方法并不属于Thread类,而是属于Object类。
但这三个方法必须同步监视器对象调用。
关于这三个方法的解释如下:
wait():导致当前线程等待,直到其他线程调用该同步监视器的notify()方法或notifyAll()方法来唤醒该线程。
该wait()方法有三种形式:无时间参数的wait(一直等待,直到其他线程通知),带毫秒参数的wait和带毫秒、微秒参数的wait
(这两种方法都是等待指定时间后自动苏醒)。
调用wait()方法的当前线程会释放对该同步监视器的锁定。
notify():唤醒在此同步监视器上等待的单个线程。如果所有线程都在此同步监视器上等待,则会选择唤醒其中一个线程。选择是任意性的。
只有当前线程放弃对该同步监视器的锁定后(使用wait()方法),才可以执行被唤醒的线程。
notifyAll():唤醒在此同步监视器上等待的所有线程。只有当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程。
wait与notify方法要注意的事项:
1. wait方法与notify方法是属于Object对象 的。
2. wait方法与notify方法必须要在同步代码块或者是同步函数中才能使用。
3. wait方法与notify方法必需要由同步监视器对象调用。
例如:
package uestc.Thread;//使用wait(),notify()实现经典的生产者与消费者问题。//产品类class Product{String name; //名字boolean flag = false; //产品是否生产完毕的标识,默认情况是false}//生产者class Producer extends Thread{Product p; //产品public Producer(Product p){this.p = p;}public void run(){int i = 0;while(true){synchronized(p){if(p.flag == false){p.name = "苹果";System.out.println("生产者生产出了:"+p.name);p.flag = true;i++;p.notify();}else{//已经生产完毕,等待消费者去消费try {p.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}//消费者class Customer extends Thread{Product p;public Customer(Product p){this.p = p;}public void run(){while(true){synchronized(p){if(p.flag == true){ //产品已经生产完毕System.out.println("消费者消费了"+p.name);p.flag = false;p.notify(); //唤醒生产者去生产}else{//产品还没有生产,应该等待生产者去生产try {p.wait(); } catch (InterruptedException e) {e.printStackTrace();}}}}}}public class Demo4 {public static void main(String[] args) {Product p = new Product(); //产品对象//创建生产对象Producer producer = new Producer(p);//创建消费者Customer customer = new Customer(p);//调用start方法开启线程producer.start();customer.start();}}
2. 线程生命周期
任何事物都是生命周期,线程也是,
1. 正常终止 当线程的run()执行完毕,线程死亡。
2. 使用标记停止线程
注意:Stop方法已过时,就不能再使用这个方法。
3. 如果需要停止一个处于等待状态下的线程,那么我们需要通过变量配合notify方法或者interrupt()来使用。
如何使用标记停止线程停止线程。
开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以让run方法结束,线程就结束。
3. 后台线程(守护线程)
后台线程:就是隐藏起来一直在默默运行的线程,直到进程结束。
实现:
setDaemon(boolean on) 例如:d.setDaemon(true); //setDaemon() 设置d线程是否为守护线程,true为守护线程, false为非守护线程
特点:
当所有的非后台线程结束时,程序也就终止了同时还会杀死进程中的所有后台线程,也就是说,只要有非后台线程还在运行,程序就不会终止,执行main方法的主线程就是一个非后台线程。
必须在启动线程之前(调用start方法之前)调用setDaemon(true)方法,才可以把该线程设置为后台线程。
可以使用isDaemon() 测试该线程是否为后台线程(守护线程)。 例如:System.out.println("是守护线程吗?"+ d.isDaemon()); //判断线程是否为守护线程。
4.Thread的join方法
当A线程执行到了B线程Join方法时A就会等待,等B线程都执行完A才会执行,Join可以用来临时加入线程执行。
join()方法通常由使用线程的程序调用,以将大问题划分成许多小问题,每个小问题分配一个线程。
当所有的小问题都得到处理后,再调用主线程来进一步操作。
- Java中线程的通信
- Java中线程的通信
- Java中线程通信
- 在Java中,关于线程的通信
- Java中线程通信的方法
- java中线程间的通信
- java的线程通信
- Java中线程通信协作
- java中传统的线程通信个人见解
- java中传统的线程通信个人见解
- Java中线程间的通信(synchronized,wait,notify)
- JAVA线程间的通信
- java线程之间的通信
- java线程间的通信
- Java 线程间的通信
- java间的线程通信
- Java线程之间的通信
- java线程之间的通信
- OpenGL绘制填充非凸边形
- 多管齐下、与时俱进,唯品会再创佳绩
- HTML5新增标签2,视频,音频,调节颜色
- Java基础(15):集合
- linux /centos 中OpenSSL升级方法详解
- Java中线程的通信
- Julia: Dict类型 与 Symbol
- 文本文件读取截取以及存储
- 九度oj-1124-Digital Roots
- final修饰符---final方法
- 分享一个网页代码
- 关于字符编码延伸出来的
- 计算机科学不等于数学
- LightOJ 题目1027 - A Dangerous Maze(期望)