20140217 问题解决: 参考
第21章 - 并发 - 单一生产者与消费者,多个生产者与多个消费者(P709)
http://jackyin5918.iteye.com/blog/2018319
主要原因是因为使用单一锁,单一条件,使用Lock 创建两个Condition 根据不同条件调用不同condition.的signalAll()方法.
下面这个代码参考:http://www.cnblogs.com/Gordon-YangYiBao/archive/2012/09/16/2687520.html
原文说用notifyAll替代notify可解决死锁,其实不行,还是死锁,解决方法还未实现
package com.app.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * * 辅助类OutTurn的一个方法输出基数,一个方法输出偶数,两个方法均有通过同步交替输出. * 同步条件isOdd==true是输出基数,isOdd==false输出偶数 * 主类LockDemo,中实现两个runnable,OddPrinter和EvenPrinter分别输出基数和偶数 * */ public class LockDemo { private static final OutTurn ot = new OutTurn(); public static void main(String[] args) { // System.out.println("lock"); ExecutorService service = Executors.newCachedThreadPool(); for (int j = 0; j < 10000; j++) //这里要循环次数大一些的,否则不容易出现死锁 { service.submit(new OddPrinter()); service.submit(new EvenPrinter()); } service.shutdown(); } /** * printEven (((((((((((( 5202 printOdd ---- 5203 printEven (((((((((((( 5204 printOdd ---- 5205 printEven (((((((((((( 5206 * 运行到上面时卡住了,表示死锁了. * 分析: 上面是输出5026后死锁的,此时isOdd=true,然后调用notify方法,此方法 * 唤醒一个线程(其他线程都处于等待状态),假如唤醒的线程还是EvenPrinter,则此线程会立即 * 执行 * while (isOdd) { this.wait(); } 此时,这个唯一的唤醒的线程也处于等待状态,然后 所有线程都处于等待状态了,然后导致死锁. 将所有的notify方法换成notifyAll方法 还是不行 * */ static class OddPrinter implements Runnable { @Override public void run() { ot.printOdd(); } } static class EvenPrinter implements Runnable { @Override public void run() { ot.printEven(); } } } class OutTurn { private boolean isOdd = true; private int count = 1; public synchronized void printOdd() { try { while (!isOdd) { this.wait(); } System.out.println("printOdd ---- " + count); isOdd = false; this.notifyAll(); } catch (Exception e) { e.printStackTrace(); } count++; } public synchronized void printEven() { try { while (isOdd) { this.wait(); } System.out.println("printEven (((((((((((( " + count); isOdd = true; this.notifyAll(); } catch (Exception e) { e.printStackTrace(); } count++; } }
相关推荐
源码—Java多线程5—死锁和wait notify notifyAll
在Java中,`wait()`, `notify()`, 和 `notifyAll()` 是Java Object类的三个方法,它们在实现线程间通信和协作时扮演着关键角色。这些方法主要用于解决线程等待和唤醒的问题,是基于Java Monitor(监视器)模型的。 ...
总结来说,`notify()`和`notifyAll()`之间的主要区别在于唤醒线程的数量和死锁的风险。`notify()`仅唤醒一个线程,可能导致死锁或不一致的状态,而`notifyAll()`唤醒所有线程,尽管可能增加资源消耗,但在多数情况下...
Java中的`notify`和`notifyAll`方法是多线程编程中的重要概念,它们都是`Object`类的方法,用于在同步控制中唤醒等待在特定对象监视器上的线程。理解这两个方法的区别对于编写高效的并发代码至关重要。 首先,`...
4. **死锁和饥饿**:虽然`wait()`, `notify()`, `notifyAll()` 提供了线程间的通信,但不当使用可能导致死锁(两个或更多线程互相等待对方释放资源而无法继续执行)或饥饿(某些线程一直无法获取资源而无法执行)的...
它们提供了一种精细控制线程间交互的方式,但使用时需谨慎,避免死锁和活锁的发生。 总之,理解和熟练掌握`wait()`, `notify()`以及`sleep()`的使用对于编写高效的多线程程序至关重要。在设计并发程序时,应根据...
使用wait/notify机制时,需要注意死锁和活锁问题。死锁发生在两个或更多线程互相等待对方释放资源的情况下。活锁则是线程不断尝试获取资源但一直失败,导致无限期阻塞。合理设计同步策略和避免这些情况是多线程编程...
`wait()`、`notify()`和`notifyAll()`方法是Java中实现线程同步的关键工具。正确使用它们可以有效避免线程间的竞争条件和死锁问题,同时也能实现线程间的高效通信。在实际开发中,应根据具体的应用场景选择合适的...
在Java中,死锁通常与多线程同步有关,尤其是当使用synchronized关键字和wait()、notify()、notifyAll()方法时,如果没有正确管理,就可能导致死锁的发生。 死锁的四个必要条件是: 1. 互斥条件:至少有一个资源是...
此外,为了防止死锁和饥饿现象,合理地设计同步策略和唤醒逻辑至关重要。 总结来说,`wait`、`notify`和`notifyAll`是Java多线程中实现线程间通信的关键工具,它们允许线程在适当的时候释放资源并等待,以便其他...
Java多线程编程中,`wait()`, `notify()`, 和 `notifyAll()` 是三个非常重要的方法,它们用于线程间通信和同步。这些方法并不是定义在 `Thread` 类中的,而是作为 `Object` 类的一部分,这意味着任何Java对象都可以...
在Java多线程编程中,`notify()`和`notifyAll()`是两个非常关键的方法,它们用于线程间的通信,特别是与`wait()`方法配合使用时,可以实现线程的同步和协作。这两个方法都是`Object`类的方法,因此所有Java对象都...
Java提供了如`synchronized`关键字、`wait()`、`notify()`和`notifyAll()`等工具来管理线程间的同步与通信,防止死锁的发生。 死锁的四个必要条件包括: 1. 互斥:至少有一个资源在任何时候只能由一个进程使用。 2....
- 调用`b.wait()`,这会让当前线程进入等待状态,直到另一个线程调用`b.notify()`或`b.notifyAll()`唤醒它。 - 输出完成后的总和。 - **`ThreadB`类**: - 继承自`Thread`类,重写了`run`方法。 - 在`run`方法...
notify可能会导致死锁,而notifyAll则不会。notifyAll可以唤醒所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个线程。 四、sleep和wait的区别 sleep和wait都是用于线程暂停执行的方法,...
正确使用这些方法可以有效避免线程间的死锁和资源浪费,同时保证多线程程序的正确性和性能。然而,使用这些方法时也需谨慎,不当的使用可能导致线程饥饿或其他并发问题。因此,深入理解Java的线程模型和锁机制是编写...
5. **线程安全**:通过使用synchronized关键字和wait/notify机制,保证了在多线程环境下,存款和取款操作的正确性,避免了数据竞争和死锁等问题。 6. **线程启动**:通过调用`Thread.start()`启动线程,使得新线程...
使用`wait()`、`notify()`和`notifyAll()`方法进行线程间的通信,可以避免因资源争夺造成的死锁。 9. **资源有序分配策略**: 对于可能出现死锁的资源,强制规定线程必须按照一定的顺序请求资源,从而打破循环...
- 使用wait、notify和notifyAll时,应避免死锁和活锁。 ### 三、Lock接口 Java 5引入了java.util.concurrent.locks包,其中的Lock接口提供了比synchronized更细粒度的锁控制。Lock接口提供了一些额外的功能,如可...
而其他线程可以通过 `notify()` 或 `notifyAll()` 来唤醒等待的线程。 3. **Lock 接口(ReentrantLock)**:自 Java 5 引入,提供了更细粒度的锁控制。`ReentrantLock` 是 Lock 接口的实现类,提供了 `lock()`、`...