代码分析Java中线程的等待与唤醒

我们先来看一下实例代码:

class ThreadA extends Thread{

  public ThreadA(String name) {
    super(name);
  }

  public void run() {
    synchronized (this) {
      System.out.println(Thread.currentThread().getName()+" call notify()");
      notify();
    }
  }
}
public class WaitTest {
  public static void main(String[] args) {
    ThreadA t1 = new ThreadA("t1");
    synchronized(t1) {
      try {
        // 启动“线程t1”
        System.out.println(Thread.currentThread().getName()+" start t1");
        t1.start();

        // 主线程等待t1通过notify()唤醒。
        System.out.println(Thread.currentThread().getName()+" wait()");
        t1.wait();

        System.out.println(Thread.currentThread().getName()+" continue");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

输出结果:main start t1 -> main wait() -> t1 call notify() -> main continue

其实调用t1.start(),t1为就绪状态,只是main方法中,t1被main线程锁住了,t1.wait()的时候,让当前线程等待,其实是让main线程等待了,然后释放了t1锁,t1线程执行,打印t1 call notify(),然后唤醒main线程,最后结束;

这里说一下wait()与sleep()的区别,他们的共同点都是让线程休眠,但是wait()会释放对象同步锁,而sleep()不会;下面的代码t1结束之后才会运行t2;能够证实这一点;

public class SleepLockTest{
  private static Object obj = new Object();
  public static void main(String[] args){
    ThreadA t1 = new ThreadA("t1");
    ThreadA t2 = new ThreadA("t2");
    t1.start();
    t2.start();
  }
  static class ThreadA extends Thread{
    public ThreadA(String name){
      super(name);
    }
    public void run(){
      synchronized (obj) {
        try {
          for(int i=0; i <10; i++){
            System.out.printf("%s: %d\n", this.getName(), i);
            // i能被4整除时,休眠100毫秒
            if (i%4 == 0)
              Thread.sleep(100);
          }
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }
}
(0)

相关推荐

  • java基本教程之java线程等待与java唤醒线程 java多线程教程

    本章,会对线程等待/唤醒方法进行介绍.涉及到的内容包括:1. wait(), notify(), notifyAll()等方法介绍2. wait()和notify()3. wait(long timeout)和notify()4. wait() 和 notifyAll()5. 为什么notify(), wait()等函数定义在Object中,而不是Thread中 wait(), notify(), notifyAll()等方法介绍在Object.java中,定义了wait(), notify()

  • Java中线程的等待与唤醒_动力节点Java学院整理

    wait(), notify(), notifyAll()等方法介绍 在Object.java中,定义了wait(), notify()和notifyAll()等接口.wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁.而notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程:notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程. Object类中关于等待/唤醒的API详细信息如下: notify()      

  • Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解

    前言 前面的例子都是多个线程在做相同的操作,比如4个线程都对共享数据做tickets–操作.大多情况下,程序中需要不同的线程做不同的事,比如一个线程对共享变量做tickets++操作,另一个线程对共享变量做tickets–操作,这就是大名鼎鼎的生产者和消费者模式. 正文 一,生产者-消费者模式也是多线程 生产者和消费者模式也是多线程的范例.所以其编程需要遵循多线程的规矩. 首先,既然是多线程,就必然要使用同步.上回说到,synchronized关键字在修饰函数的时候,使用的是"this"

  • Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll)

    本篇我们来研究一下 wait() notify() notifyAll() . DEMO1: wait() 与 notify() public class Test { static class ThreadOne extends Thread { private Callback mCallback; @Override public void run() { work(); if (mCallback != null) { mCallback.onResult(false); } } //

  • 代码分析Java中线程的等待与唤醒

    我们先来看一下实例代码: class ThreadA extends Thread{ public ThreadA(String name) { super(name); } public void run() { synchronized (this) { System.out.println(Thread.currentThread().getName()+" call notify()"); notify(); } } } public class WaitTest { publ

  • 代码分析JAVA中PCM人声音频变声处理

    项目中需要用到对PCM人声音频数据进行变声处理.苦苦挣扎了一周终于找到了纯Java实现的一套框架--TarsosDSP.功能非常强大!可以实时音频处理!当然我只用到了对文件处理.实际上逻辑是一样的 TarsosDSP的GitHub地址:https://github.com/JorenSix/TarsosDSP 将它整合至自己的项目工程. 具体Java工具类代码: /** * 变声 * @param rawPcmInputStream 原始PCM数据输入流 * @param speedFactor

  • java 中线程等待与通知的实现

    java 中线程等待与通知的实现 前言: 关于等待/通知,要记住的关键点是: 必须从同步环境内调用wait().notify().notifyAll()方法.线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁. wait().notify().notifyAll()都是Object的实例方法.与每个对象具有锁一样,每个对象可以有一个线程列表,他们等待来自该信号(通知).线程通过执行对象上的wait()方法获得这个等待列表.从那时候起,它不再执行任何其他指令,直到调用对象的notify()

  • Java中线程的基本方法使用技巧

    java中线程的基本方法的熟练使用是精通多线程编程的必经之路,线程相关的基本方法有wait,notify,notifyAll,sleep,join,yield等,本文浅要的介绍一下它们的使用方式. 线程的状态图 java将操作系统中的就绪和运行两种状态统称为可运行状态,java中线程的状态可以认为有以上六种. wait 调用该方法的线程进入WAITING状态,只有等待另外线程的通知或被中断才会返回,需要注意的是调用wait()方法后,会释放对象的锁. 因此,wait方法一般用在同步方法或同步代码

  • 分析java中全面的单例模式多种实现方式

    一.单例模式的思想 想整理一些 java 并发相关的知识,不知道从哪开始,想起了单例模式中要考虑的线程安全,就从单例模式开始吧.以前写过单例模式,这里再重新汇总补充整理一下,单例模式的多种实现. 单例模式的主要思想是: 将构造方法私有化( 声明为 private ),这样外界不能随意 new 出新的实例对象: 声明一个私有的静态的实例对象,供外界使用: 提供一个公开的方法,让外界获得该类的实例对象 这种说法看上去没错,但也好像不太准确.其实,就算外界能随意 new 出新的实例对象,但只要我们保证

  • Java中线程安全问题

    目录 一.线程不安全 二.那些情况导致了线程不安全? 三.Java中解决线程不安全的方案 1.volatile"轻量级"解决线程不安全 2.synchronized自动加锁 四.公平锁与非公平锁机制 五.volatile和synchronized的区别 六.synchronized和Lock的区别 一.线程不安全 多线程的执行环境中,程序的执行结果和预期的结果不符合,这就称为发生了线程不安全现象 二.那些情况导致了线程不安全? 大致分为以下5种情况: (1)CPU抢占执行 (无法解决)

  • java中线程池最实用的创建与关闭指南

    目录 前言 线程池创建 只需要执行shutdown就可以优雅关闭 执行shutdownNow关闭的测试 总结 前言 在日常的开发工作当中,线程池往往承载着一个应用中最重要的业务逻辑,因此我们有必要更多地去关注线程池的执行情况,包括异常的处理和分析等. 线程池创建 避免使用Executors创建线程池,主要是避免使用其中的默认实现,那么我们可以自己直接调用ThreadPoolExecutor的构造函数来自己创建线程池.在创建的同时,给BlockQueue指定容量就可以了. private stat

  • 关于java中线程安全问题详解

    目录 一.什么时候数据在多线程并发的环境下会存在安全问题? 二.怎么解决线程安全问题? 三.银行 取钱/存钱 案例 为什么会出现线程安全问题 四.总结 一.什么时候数据在多线程并发的环境下会存在安全问题? 三个条件: 条件1:多线程并发. 条件2:有共享数据. 条件3:共享数据有修改的行为. 满足以上3个条件之后,就会存在线程安全问题. 二.怎么解决线程安全问题?         线程排队执行.(不能并发).用排队执行解决线程安全问题.这种机制被称为:线程同步机制. 三.银行 取钱/存钱 案例

  • 分析Android中线程和线程池

    目录 前言 HandlerThread IntentService 线程池的好处 ThreadPoolExecutor 线程池的分类 FixedThreadPool CachedThreadPool ScheduledThreadPool SingleThreadExecutor 前言 由于内容过多,所以将分为上下两部分,第一部分主要和大家谈谈Android中的线程,以及在Android中的常用的线程池.第二部分我们一起来了解一下AsyncTask的使用和工作原理. HandlerThread

随机推荐