jvm多个线程间的通信是通过 线程的锁、条件语句、以及wait()、notify()/notifyAll组成。

下面来实现一个启用多个线程来循环的输出两个不同的语句。

package com.app.thread;

import javax.swing.plaf.SliderUI;
/**
 * 看出问题来
 * @author Gordon
 *
 */
public class LockDemo {
 public static void main(String[] args) {
//  System.out.println("lock");

final OutTurn ot = new OutTurn();
  
  for(int j=0;j<100;j++){

new Thread(new Runnable() {

public void run() {
//     try {
//      Thread.sleep(10);
//     } catch (InterruptedException e) {
//      e.printStackTrace();
//     }
     for (int i = 0; i <5; i++) {     
      ot.sub();
     }
    }
   }).start();

new Thread(new Runnable() {

public void run() {
//     try {
//      Thread.sleep(10);
//     } catch (InterruptedException e) {
//      e.printStackTrace();
//     }
     for (int i = 0; i < 5; i++) {     
      ot.main();
     }
    }
   }).start();
  }

}
}

class OutTurn {
 private boolean isSub = true;
 private int count=0;

public synchronized void sub() {
  try {
   while (!isSub) {
    this.wait();
   }
   System.out.println("sub ---- "+count);
   isSub=false;
   this.notify();
  } catch (Exception e) {
   e.printStackTrace();
  }
  count++;

}

public synchronized void main() {
  try {
   while(isSub){
    this.wait();
   }
   System.out.println("main (((((((((((( "+count);
   isSub=true;
   this.notify();
  } catch (Exception e) {
   e.printStackTrace();
  }
  count++;
 }
}

不知能否看出问题,第一次写的时候出现了问题,找了很久才找了出来,一直以来是没有注意notify与notifyAll()的使用,在此酿成大错,哎。。。

说明一下notify与notifyAll的区别:

  以上sub和main方法都是用了锁,所以说多个调用sub方法的线程和多个调用main方法的都会处于阻塞状态,都会等待一个正在运行的其他线程来唤醒他们,以上代码使用了notify进行唤醒,notify只能唤醒一个线程,其他等待的线程仍然处于wait状态,如果调用sub方法的线程执行完后,所有的线程都处于等待状态,isSub=false了,这时唤醒的是一个sub方法调度线程,那么while循环等于true,则该线程也会处于等待状态,之后所有的线程处于等待状态,没有运行的线程来唤醒他们,这时就产生了死锁。如果使用notifyAll()来唤醒所有正在等待该锁的线程,那么所有的线程都会处于运行前的准备状态,就是sub方法执行完后,唤醒了所有等待该锁的状态,那么即使再次唤醒一个sub方法调度线程,那么该线程再次处于等待状态后,还有其他的线程可以获得该锁,进入运行状态。所以notify方法很容易引起死锁,除非你根据自己的程序设计,确定不会引起死锁,notifyAll则是线程的安全唤醒方法。

言归正传,以上代码 只需要将sub和main方法中的参数改成this.notifyAll()即可。

java 线程之间通信以及notify与notifyAll区别。的更多相关文章

  1. Java线程之间通信

    用多线程的目的:更好的利用CPU的资源.因为所有的多线程代码都可以用单线程来实现. 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程. 并行:多个CPU实例或者多台机器同时执行一段处理逻辑, ...

  2. java 线程之间的协作 wait()与notifyAll()

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  3. 如何在 Java 中正确使用 wait, notify 和 notifyAll(转)

    wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...

  4. 如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

    wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...

  5. Java线程间通信-回调的实现方式

    Java线程间通信-回调的实现方式   Java线程间通信是非常复杂的问题的.线程间通信问题本质上是如何将与线程相关的变量或者对象传递给别的线程,从而实现交互.   比如举一个简单例子,有一个多线程的 ...

  6. (转载) Android两个子线程之间通信

    Android两个子线程之间通信 标签: classthreadandroid子线程通信 2015-03-20 17:03 3239人阅读 评论(0) 收藏 举报  分类: 个人杂谈 版权声明:本文为 ...

  7. 关于CPU核心,线程,进程,并发,并行,及java线程之间的关系

    前言:作为一个转行java的小白,一直搞不清楚java中的多线程.于是来梳理一下关于CPU核心,线程,进程,并发,并行,及java线程之间的关系, 1.CPU角度来看: 我们以Intel的Core i ...

  8. Java线程间通信之wait/notify

    Java中的wait/notify/notifyAll可用来实现线程间通信,是Object类的方法,这三个方法都是native方法,是平台相关的,常用来实现生产者/消费者模式.我们来看下相关定义: w ...

  9. java线程之间的通信

    1.常用的方法 sleep() 该线程进入等待状态,不释放锁 wait() 该线程进入等待状态,释放锁 notify() 随机唤醒一个线程 notifyAll() 唤醒全部线程 getName() 获 ...

随机推荐

  1. 初探swift语言的学习笔记七(swift 的关健词)

    每一种语言都有相应的关键词,每个关键词都有他独特的作用,来看看swfit中的关键词: 关键词: 用来声明的: “ class, deinit, enum, extension, func, impor ...

  2. DevExpress GridControl一些属性使用方法总结

    一.如何解决单击记录整行选中的问题 View->OptionsBehavior->EditorShowMode 设置为:Click 二.如何新增一条记录 (1).gridView.AddN ...

  3. L10 安装网卡驱动

    一.安装网卡驱动 1. 检查各种依赖包是否安装 2. 安装 加载网卡驱动: ip:

  4. 关于DLL中Resources文件修改

    1.先用IL DASM工具将所需要修改的DLL进行文件转换成IL文件,其中*.il文件就是代码,*.resources,这个文件就是资源. 2.找到需要修改的resources文件 //新文件 IRe ...

  5. C# 过滤特殊字符

    . /// <summary> /// 过滤不安全的字符串 /// </summary> /// <param name="Str"></ ...

  6. Qt5 文本编辑

    [应用场景]:在编辑框中输入一段文字,用鼠标选取文字,修改工具栏上的字体.字号大小.加粗.斜体等属性,选取的文字即发生相应的变化.       一. 任何一个文本编辑器的程序都要用到QTextEdit ...

  7. mysql优化(1) 观察服务器周期性变化

    先把nginx和memcached环境开启 /usr/local/nginx/sbin/nginx /usr/local/fastphp/sbin/php-fpm /usr/local/memcach ...

  8. linux安装php5.3

    安装php的依赖包 [root@localhost admin]# unzip libxml2-2.7.8.tar.zip [root@localhost admin]#tar zvxf libxml ...

  9. hql中in的用法

    平时经常用Hibernate,由于习惯表间不建立关联,所以HQL查询时候经常要用in语句. 由于表间没有建立外键的关联关系所以使用in是最常见的代替使用对象po中的set. 但是在写hql时如果在ne ...

  10. Android周笔记(9.8-14)(持续更新)

    本笔记记录一周内的小知识点和一些心学习的Demo. 1.PopupWindow: new 一个activity_pop_window:id为popwindow的Button,id为hello123的T ...