`
booby325
  • 浏览: 386534 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java多线程设计wait/notify机制 (synchronized与对象锁)

 
阅读更多

java多线程设计wait/notify机制 (synchronized与对象锁)

 

synchronized(obj) {
    while(!condition) {
        obj.wait();
    }
    obj.doSomething();
}

当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait() , 放弃对象锁.

之后在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:

synchronized(obj) {
    condition = true;
    obj.notify();
}

需要注意的概念是:

# 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {…} 代码段内。

# 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {…} 代码段内唤醒A。

# 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。

# 如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。

# obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。

# 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。

 

比如下述代码,在SubThread中,如果只是notify,而没有wait,那么SubThread仍然持有lock锁,MyThread虽然被唤醒,但是仍然要等待SubThread执行结束。

package test.thread;

//2个线程交替打印。线程1打印奇数,线程2打印偶数
public class ThreadTest {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String lock = "lock";
		MyThread myThread = new MyThread(lock);
		Thread t1 = new Thread(myThread);
		t1.start();
		try {
			// 确保线程t1先执行
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		SubThread sub = new SubThread(lock);
		Thread t2 = new Thread(sub);
		t2.start();
	}
}

class MyThread implements Runnable {
	String lock;

	public MyThread(String lock) {
		this.lock = lock;//当前线程获得lock对象的引用
	}

	public void run() {
		int i = 0;
		// 使用lock对象作为监视器
		synchronized (lock) {//在lock对象上加锁
			System.out.println("The first thread.获得锁");
			while (i++ < 20) {
				try {
					// 每次暂停500毫秒是为了更好地看到效果
					Thread.sleep(500);
					if (i%2==1) {
						System.out.println("The first thread.-->" + i);
						// 调用lock监视器的wait()方法,通知本线程释放监视器,本线程等待
						// 其他也使用lock对象作为监视器的线程唤醒的时候,本线程得以继续运行
						System.out.println("The first thread 被阻塞");
						lock.wait();
						// 下面的wait(long timeout)表示:若等待5秒后还没有别的线程来唤醒的话,则本线程继续执行
						// lock.wait(5000);
					}else{
						System.out.println("The first thread 解锁lock");
						lock.notify();
					}
					//这个线程当是奇数时,打印数字,打印后,此线程wait。当是偶数时,什么都不做,只是激活lock对象
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

class SubThread implements Runnable {
	String lock;

	public SubThread(String lock) {
		this.lock = lock;
	}

	public void run() {
		int i = 1;
		// 这个线程也使用lock对象作为监视器
		synchronized (lock) {
			System.out.println("The second thread.获得锁");
			while (i < 20) {
				try {
					Thread.sleep(500);
					if (i%2==0) {
						System.out.println("The second thread.-->" + i);
						// 调用lock监视器的wait()方法,通知本线程释放监视器,本线程等待
						// 其他也使用lock对象作为监视器的线程唤醒的时候,本线程得以继续运行
						
						System.out.println("The second thread 解锁lock");
						lock.notify();
						
						System.out.println("The second thread 被阻塞");
						lock.wait();
						// 下面的wait(long timeout)表示:若等待5秒后还没有别的线程来唤醒的话,则本线程继续执行
						// lock.wait(5000);
					}else{
						System.out.println("The second thread 什么也没干");
						//lock.notify();
					}
					i++;
					//这个线程2,当线程1的wait调用时,此线程2激活。当i是偶数时,打印i,打印后,通知lock解锁(此时thread1得锁,干活),并且此线程2被阻塞
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			// 调用lock对象的notify()方法,唤醒同一对象监视器中调用wait的第一线程
			// 或者调用notifyAll()方法,唤醒同一对象监视器中调用wait的所有线程,具有最高优先级的线程首先被唤醒并执行
			//lock.notify();
		}
	}
}
 
分享到:
评论

相关推荐

    Java 同步方式 wait和notify/notifyall

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

    java多线程设计wait[参考].pdf

    Java中的多线程设计涉及到许多核心概念,其中wait/notify机制是实现线程间通信和协作的关键工具。这个机制主要用于解决资源的分配和同步问题,它依赖于Java的内置锁机制,即`synchronized`关键字和对象锁。 首先,...

    Java多线程wait和notify

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

    浅谈java多线程wait,notify

    _java多线程wait、notify机制详解_ 在Java多线程编程中,wait和notify是两个非常重要的机制,用于实现线程之间的通信和同步。在本文中,我们将通过示例代码详细介绍Java多线程wait和notify的使用,帮助读者更好地...

    java多线程设计wait.docx

    ### Java多线程设计之Wait/Notify机制详解 #### 一、引言 在Java并发编程中,`wait()`和`notify()`是非常重要的同步机制,它们通常与`synchronized`关键字一起使用,帮助开发者解决线程间的协作问题。本文将深入...

    Java 同步锁 wait notify 学习心得

    标题和描述概述的知识点主要集中在Java的多线程机制中,特别是`wait`和`notify`方法在同步锁中的应用。这些方法对于控制线程之间的交互至关重要,尤其是在资源有限或需要确保数据一致性的情况下。 ### Java同步锁...

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

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

    java多线程设计模式详解(PDF及源码)

    (注意,本资源附带书中源代码可供参考) 多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字与实例来介绍Java线程相关的设计模式概念,并且通过实际的Java程序范例和 UML图示来一一解说,书中...

    多线程系列相关的技术要点

    5. Java多线程学习(四)等待/通知(wait/notify)机制 6. Java多线程学习(五)线程间通信知识点补充 7. Java多线程学习(六)Lock锁的使用 8. Java多线程学习(七)并发编程中一些问题 9. Java多线程学习(八...

    java多线程机制 详解

    Java的多线程机制是Java语言的一大特性,它允许程序同时执行多个任务,提升程序响应速度,优化资源利用率。在Java中,线程是程序执行的最小单位,一个进程可以包含多个线程,每个线程都有自己独立的生命周期,包括...

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

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

    Java多线程管理示例

    下面我们将深入探讨Java多线程的核心概念、同步机制、死锁问题以及wait/notify机制,以"生产者与消费者"的例子来具体阐述。 首先,了解Java中的线程。线程是操作系统分配CPU时间的基本单位,每个线程都有自己的程序...

    java多线程Demo

    在多线程环境下,可能会出现数据竞争问题,为了解决这个问题,Java提供了多种同步机制,如synchronized关键字、wait/notify机制、Lock锁(ReentrantLock)等。synchronized用于控制对共享资源的访问,而wait/notify...

    Java多线程技术在网络通信系统中的应用.pdf

    Java提供了synchronized关键字来实现线程同步锁机制,可以有效地控制对共享资源的访问,保证了多线程环境中的数据一致性。wait/notify机制是另一种重要的线程间通信手段,它允许线程在执行到某个点时可以主动让出CPU...

    Java的sychronized、wait和notify范例

    `synchronized`关键字、`wait()`和`notify()`方法是Java多线程中用于控制并发访问共享资源的重要工具,它们是Java内存模型(JMM)的一部分,主要用于解决线程间的同步问题。 一、`synchronized`关键字 `...

    Java多线程同步(wait()notify()notifyAll())[文].pdf

    - 提供的Account类示例展示了如何使用synchronized关键字和wait/notify机制来模拟多线程存取同一账户的操作。 - save()和load()方法都使用了synchronized来保证并发访问的安全性。 - load()方法中使用了wait(),...

    java多线程设计模式_java_设计模式_多线程_多线程课题_

    Java提供了多种同步机制,如synchronized关键字、wait()和notify()方法、ReentrantLock重入锁、Semaphore信号量等。synchronized用于保证同一时刻只有一个线程访问共享资源,而wait()和notify()用于线程间的通信,...

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

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

    java多线程设计模式详解(PDF及源码).zip

    Java多线程设计模式是Java开发中的重要领域,它涉及到如何高效、安全地利用系统资源进行并发处理。在这个主题中,我们将深入探讨单线程、生产者与消费者模型以及Java中实现多线程的各种方法。 首先,单线程是程序...

    Java多线程知识点总结

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

Global site tag (gtag.js) - Google Analytics