`

Java 多线程例子9 线程之间通信 wait notify notifyAll

阅读更多

下面参照《Java就业培训教材》写了一个相似的线程之间通信的例子,程序实现了一个生产者和一个消费者,还有一个buffer用于存放生产出来的一个对象,buffer中只可以存放一个对象,buffer有一个标志位bFull,如果标志位为true表示buffer里有数值,如果bFull为false表示没有数值。buffer中的对象有两个属性,在多线程中如果不处理同步的话,可能出现属性不对应的情况。

wait:告诉当前线程放弃监视器并进入睡眠状态,直到其他线程进入同一监视器并调用notify为止。

notify:唤醒同一对象监视器中调用wait的第一线程。用于类似饭馆有一个空位子后通知所有等候就餐的顾客中的第一位可以入座的情况。

notifyAll:唤醒同一对象监视器中调用wait的所有线程,具有最高优先级的线程首先被唤醒并执行。用于类似某个不定期的培训班终于招生满额后,通知所有学员都来上课的情况。

从上面明显可以看出wait、notify和notifyAll只能在synchronized方法中调用,记住一个对象的notify只能够唤醒被同一个对象wait的线程。

1,线程不同步

class ThreadDemo {
	public static void main(String[] args) {
		Buffer buf = new Buffer();
		new Producer(buf).start();
		new Consumer(buf).start();
	}
}
class Producer extends Thread {
	private Buffer buf;
	public Producer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		boolean odd = false;
		while(true) {
			if(odd) {
				buf.name="jack";	
				try{Thread.sleep(1000);}catch(Exception e) {}
				buf.sex="female";
			} else {
				buf.name="lucy";	
				try{Thread.sleep(1000);}catch(Exception e) {}
				buf.sex="male";
			}
			odd = !odd;
		}
	}
}
class Consumer extends Thread {
	private Buffer buf;
	public Consumer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		while(true) {
			try{Thread.sleep(1000);}catch(Exception e) {}
			System.out.println(buf.name + " : " + buf.sex);
		}
	}
}
class Buffer {
	boolean bFull;
	String name = "Unkown";
	String sex = "Unkown";
}

 结果 写道

jack : male
jack : female
lucy : female
lucy : female
jack : male
lucy : female
jack : male

 线程不同步回去出现jack : male,lucy : female 这些错误的输出。

2,线程同步

class ThreadDemo {
	public static void main(String[] args) {
		Buffer buf = new Buffer();
		new Producer(buf).start();
		new Consumer(buf).start();
	}
}
class Producer extends Thread {
	private Buffer buf;
	public Producer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		boolean odd = false;
		while(true) {
			synchronized(buf) {
				if(odd) {
					buf.name="jack";	
					try{Thread.sleep(100);}catch(Exception e) {}
					buf.sex="female";
				} else {
					buf.name="lucy";	
					try{Thread.sleep(100);}catch(Exception e) {}
					buf.sex="male";
				}
			}
			odd = !odd;
		}
	}
}
class Consumer extends Thread {
	private Buffer buf;
	public Consumer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		while(true) {
			synchronized(buf) {
				try{Thread.sleep(100);}catch(Exception e) {}
				System.out.println(buf.name + " : " + buf.sex);
			}
		}
	}
}
class Buffer {
	boolean bFull;
	String name = "Unkown";
	String sex = "Unkown";
}

 

结果 写道
Unkown : Unkown
lucy : male
jack : female
lucy : male
jack : female
lucy : male

 没有采用线程通信会出现Unkown : Unkown 和连续输出lucy和jack的情况。

3,线程通信 wait notify

class ThreadDemo {
	public static void main(String[] args) {
		Buffer buf = new Buffer();
		new Producer(buf).start();
		new Consumer(buf).start();
	}
}
class Producer extends Thread {
	private Buffer buf;
	public Producer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		boolean odd = false;
		while(true) {
			synchronized(buf) {
				if(buf.bFull)
					try{buf.wait();}catch(Exception e) {}
				if(odd) {
					buf.name="jack";	
					try{Thread.sleep(100);}catch(Exception e) {}
					buf.sex="female";
				} else {
					buf.name="lucy";	
					try{Thread.sleep(100);}catch(Exception e) {}
					buf.sex="male";
				}
				buf.bFull = true;
				buf.notify();
			}
			odd = !odd;
		}
	}
}
class Consumer extends Thread {
	private Buffer buf;
	public Consumer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		while(true) {
			synchronized(buf) {
				if(!buf.bFull)
					try{buf.wait();}catch(Exception e) {}
				//try{Thread.sleep(100);}catch(Exception e) {}
				System.out.println(buf.name + " : " + buf.sex);
				buf.bFull = false;
				buf.notify();
			}
		}
	}
}
class Buffer {
	boolean bFull = false;
	String name = "Unkown";
	String sex = "Unkown";
}

 

结果 写道
lucy : male
jack : female
lucy : male
jack : female
lucy : male
jack : female

 

结果达到了预期的目的。

4,面前对象 同步函数

class ThreadDemo {
	public static void main(String[] args) {
		Buffer buf = new Buffer();
		new Producer(buf).start();
		new Consumer(buf).start();
	}
}
class Producer extends Thread {
	private Buffer buf;
	public Producer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		boolean odd = false;
		while(true) {
			if(odd) {
				buf.put("jack","female");
			} else {
				buf.put("lucy","male");
			}
			odd = !odd;
		}
	}
}
class Consumer extends Thread {
	private Buffer buf;
	public Consumer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		while(true) {
			buf.get();
		}
	}
}
class Buffer {
	private boolean bFull = false;
	private String name = "Unkown";
	private String sex = "Unkown";
	
	public synchronized void put(String name, String sex) {
		if(bFull)
			try{wait();}catch(Exception e) {}
		this.name = name;
		this.sex = sex;
		bFull = true;
		notify();
	}
	public synchronized void get() {
		if(!bFull)
			try{wait();}catch(Exception e) {}
		System.out.println(name + " : " + sex);
		bFull = false;
		notify();
	}
}

 

分享到:
评论
2 楼 xmind 2010-12-10  
  
1 楼 xuzhuocool 2010-12-09  
你好 认识一下吗

相关推荐

    源码—Java多线程5—死锁和wait notify notifyAll

    源码—Java多线程5—死锁和wait notify notifyAll

    Java 同步方式 wait和notify/notifyall

    总结一下,`wait()`, `notify()`, 和 `notifyAll()` 是Java多线程编程中的核心工具,它们与`synchronized`关键字一起,为线程间的协作提供了强大的支持。理解并熟练掌握这些概念,对于编写高效、安全的多线程程序至...

    java多线程的讲解和实战

    - 等待/通知机制:`wait()`, `notify()`, `notifyAll()`方法用于线程间的通信。这些方法必须在`synchronized`环境中使用,避免线程安全问题。 - `volatile`关键字:用于标记共享变量,确保多线程环境下的可见性和...

    java 多线程并发实例

    本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是程序执行的基本单元,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈,而共享堆...

    Java多线程wait和notify

    总结来说,Java的 `wait()` 和 `notify()` 提供了一种在多线程环境中控制线程执行的机制。通过合理使用这些方法,我们可以实现线程间的协作,精确控制子线程的运行状态。然而,这种方式虽然灵活,但管理起来相对复杂...

    java多线程经典案例

    Java中,可以通过wait()、notify()和notifyAll()这三个Object类的方法来实现线程间的通信。这些方法必须在同步环境中使用,否则会抛出异常。此外,Java 5引入了BlockingQueue阻塞队列,它是一种线程安全的数据结构,...

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    JAVA多线程的实例

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应性。在Java中,实现多线程有两种主要方式:通过实现`Runnable`接口或者继承`Thread`类。 首先,让我们从创建线程开始。当你...

    汪文君JAVA多线程编程实战(完整不加密)

    《汪文君JAVA多线程编程实战》是一本专注于Java多线程编程的实战教程,由知名讲师汪文君倾力打造。这本书旨在帮助Java开发者深入理解和熟练掌握多线程编程技术,提升软件开发的效率和质量。在Java平台中,多线程是...

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制是Java编程中至关重要的一部分,它允许程序同时执行多个任务,提升应用程序的效率和响应性。以下是对各个知识点的详细说明: 9.1 Java中的线程: Java程序中的线程是在操作系统级别的线程基础上进行...

    Java多线程中wait、notify、notifyAll使用详解

    Java中多线程编程中,wait、notify、notifyAll三个方法是非常重要的,它们都是Object对象的方法,用于线程之间的通信。下面我们将详细介绍这三个方法的使用和作用。 一、wait()方法 wait()方法是使当前线程自动...

    JAVAJAVA多线程教学演示系统论文

    3. **线程同步与并发控制**:论文会深入讲解JAVA中的线程同步机制,如synchronized关键字、wait()、notify()和notifyAll()方法,以及Lock接口和ReentrantLock类的使用。此外,可能会探讨并发工具类,如Semaphore、...

    Java多线程实例图形版

    wait()、notify()和notifyAll()方法用于线程间的通信,使得线程可以等待特定条件满足后再继续执行;还有volatile关键字保证了多线程环境下的可见性和有序性,避免了线程缓存造成的数据不一致。 在这个实例中,我们...

    Java多线程实例代码

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应性。在Java中,实现多线程有两种主要方式:通过继承`Thread`类和实现`Runnable`接口。 1. 继承Thread类: 当你需要创建一...

    java多线程编程实例_Source

    2. 线程通信:wait()、notify()和notifyAll()方法用于线程间的通信。在生产者消费者模型或其他同步问题中,这些方法起到关键作用。 3. 线程状态:线程有新建、就绪、运行、阻塞和终止五种状态。实例可能涉及线程的...

    java之wait,notify的用法([ 详解+实例 ])

    在Java多线程编程中,wait和notify是两个非常重要的方法,它们都是Object类的方法,用于线程之间的通信和同步。下面我们将详细解释wait和notify的用法。 wait方法 wait方法是Object类的一个方法,用于让当前线程...

    java多线程代码案例(创建线程,主线程,线程优先级,线程组,线程同步,线程间的通信)

    本文将深入探讨Java多线程中的关键知识点,包括创建线程、主线程、线程优先级、线程组、线程同步以及线程间的通信。 1. **创建线程** 在Java中,可以通过两种方式创建线程:继承`Thread`类或实现`Runnable`接口。...

    java多线程示例

    2. wait()、notify()和notifyAll():这些方法在Object类中定义,用于线程间的通信和协作。它们必须在同步环境中使用,以避免死锁。 3. Lock接口和ReentrantLock类:Java 5引入了Lock接口,提供了比synchronized更细...

    Java多线程编程核心技术_完整版_java_

    1. wait()、notify()和notifyAll():这三个方法用于线程间的通信,它们必须在同步环境中使用。 2. Condition接口:配合Lock使用,提供更灵活的线程间通信方式。 五、线程池 1. Executor框架:Java 5引入的...

    Java多线程实现异步调用实例

    标签“多线程”强调了Java并发编程的核心概念,如线程的创建、同步、通信和状态管理。例如,`synchronized`关键字用于确保对共享资源的互斥访问,防止数据竞争;`wait()`, `notify()`和`notifyAll()`方法用于线程间...

Global site tag (gtag.js) - Google Analytics