Java中线程的通信

原创 2015年11月18日 21:54:34

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多线程中线程之间的通信方式的理解,主要以代码结合文字的方式来讨论线程间的通信,故摘抄了书中的一些示例代码。 二,线程间的通信方式 ①同步 ...
  • u013066730
  • u013066730
  • 2016年08月29日 14:30
  • 2205

java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)

多线程系列教程: java多线程-概念&创建启动&中断&守护线程&优先级&线程状态(一) java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(二) 本篇我...
  • javazejian
  • javazejian
  • 2016年03月13日 16:58
  • 10377

子线程和主线程的通信问题

题目: 子线程循环执行100次,接着到主线程执行20次,然后又到子线程执行100次,再到主线程执行20次,如此交替循环50次,请写出程序。分析: 首先从这道题中我们要明确一点,就是程序中只有一个子...
  • huangxuanheng
  • huangxuanheng
  • 2015年07月21日 22:19
  • 1871

JAVA线程与线程、进程与进程间通信

I.线程与线程间通信 一、多线程间通信方式: 1、共享变量 2、wait/notify机制 3、Lock/Condition机制 二、共享变量 线程间发送信号的一个简单方式是在共享对象的变量里设置信...
  • ls5718
  • ls5718
  • 2016年07月11日 10:54
  • 11118

java线程的通信和线程池

1.传统的线程通信    使用synchronized修饰的同步方法或者同步代码块,则要在方法体重直接调用wait()、notify()和notifyAll()3个方法。其中:    wait():使...
  • zhangheng837964767
  • zhangheng837964767
  • 2013年12月20日 20:12
  • 912

Thinking in Java---线程通信+三种方式实现生产者消费者问题

前面讲过线程之间的同步问题;同步问题主要是为了保证对共享资源的并发访问不会出错,主要的思想是一次只让一个线程去访问共享资源,我们是通过加锁的方法实现。但是有时候我们还需要安排几个线程的执行次序,而在系...
  • acm_lkl
  • acm_lkl
  • 2015年08月31日 20:31
  • 1079

线程之间的通信(thread signal)

线程通信的目的是为了能够让线程之间相互发送信号。另外,线程通信还能够使得线程等待其它线程的信号,比如,线程B可以等待线程A的信号,这个信号可以是线程A已经处理完成的信号。通过共享对象通信有一个简单的实...
  • suifeng3051
  • suifeng3051
  • 2016年07月08日 17:57
  • 3386

JAVA线程间通信的几种方式

今天在群里面看到一个很有意思的面试题: “编写两个线程,一个线程打印1~25,另一个线程打印字母A~Z,打印顺序为12A34B56C……5152Z,要求使用线程间的通信。” 这是一道非常好的面试题...
  • hmiter
  • hmiter
  • 2017年03月03日 10:10
  • 2757

Java里如何实现线程间通信?

正常情况下,每个子线程完成各自的任务就可以结束了。不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了。 本文涉及到的知识点:thread.join(), object....
  • djwmzyl
  • djwmzyl
  • 2017年04月17日 14:16
  • 1326

Android:使用Handler在线程之间通信

安卓程序的Handler通信是为了解决线程之间的通信问题提出的一个机制,网上对这个机制的讲解很多,但是都不能让我很清楚的理解这个东西,所以就自己探索了一下。希望能够对跟我一样想寻找Handler“真谛...
  • LeeHDsniper
  • LeeHDsniper
  • 2016年04月16日 20:22
  • 5112
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java中线程的通信
举报原因:
原因补充:

(最多只允许输入30个字)