初识java多线程的wait(), notify()方法

多线程中wait()、sleep()、notify()和notifyAll()方法异同点【面试】 现在面试基本上都会被问及到多线程,就有很高概率问到wait() 和 sleep() 这两者的区别 1、wait()、sleep() 方法相同点 (1)都是对线程的操作; (2)都需要抛异常; (这一点我遇到很多人答错,记住这两者都会抛异常) (3)都会让当前运行线程进入阻塞状态。 2、wait()、sleep() 方法不同点 (1)使用位置不同: wait() 方法必须在同步代码中,sleep() 则不需要; (2)申明位置不同: wait() 方法是 Object类 中的方法,sleep() 方法是 T. 阅读详情

初识java多线程的wait(), notify()方法

    最近需要数据,研究了爬虫。后来发现单线程爬虫的速度不快,又研究了一下多线程。啊啊啊啊!我的文本情感分析之路什么时候才能开始呀。QAQ


本文参考了 :http://www.cnblogs.com/lwbqqyumidi/p/3817517.html

1,简介

    在多线程编程的过程中,往往会涉及到线程间的通信以及公共资源的使用。为此java提供了若干方法。wait()和notify()用于进程间的通信,synchronized用于共享资源的使用权限。
    本文将通过两个线程分别输出单数和双数的例子介绍wait()和 notify()方法。

2,wait()和notify()

    wait()和notify()函数在上述参考博客的定义如下:
这里写图片描述
开始看不明白notify()唤醒同步锁上的其他等待线程是什么意思。看了博主给的例子也不太明白。所以自己就写了一个输出单双数的程序帮助理解。程序主要是开两个线程,共享一个变量i,当i是单数的时候,由线程A输出i的值,当i是双数的时候用线程B输出i的值。共享变量i放在一个count的class中。代码如下:

class count {
    private int i;
    //是否为单数
    private boolean flag = true;
    public count(int i) {
        this.i = i;
    }
    //打印单数
    public synchronized void print_single() throws InterruptedException {
        for(int j = 0; j < 10; j++) {
            if(flag) {
                System.out.println(Thread.currentThread().getName() + "---" + i + ",单数," + j);
                i++;
                flag = false;
                notify();
            } else {
                wait();
            }
        }
    }

    //打印双数
    public synchronized void print_double() throws InterruptedException {
        for(int j = 0; j < 10; j++) {
            if(flag) {
                wait();
            } else {
                System.out.println(Thread.currentThread().getName() + "---" + i + ",双数," + j);
                i++;
                flag = true;
                notify();
            }
        }
    }
}

类中还包含打印单数和打印双数的函数。在使用wait()和notify()函数的时候,一定要将这两个函数放在synchronized中。count类中还有个标志位flag,用于判断i是否为单数。
同时写了两个实现Runnable的线程类用于调用count类中的输出单双数的函数。代码如下:

//创建一个新线程用于调用count类中的输出单数的函数
class singleRunnable implements Runnable {
    private count c;

    public singleRunnable(count c) {
        this.c = c;
    }

    public void run() {
        try {
            c.print_single();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
//创建一个新线程用于调用count类中的输出双数的函数
class doubleRunnable implements Runnable {
    private count c;

    public doubleRunnable(count c) {
        this.c = c;
    }

    public void run() {
        try {
            c.print_double();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

两个线程类中各有一个count的对象,在主程序中将会把同一个count对象传给这两个线程类作为两个线程类的公共资源。
最后是主函数。用于创建一个count对象和两个线程类并启动这两个线程。

public static void main(String[] args) throws IOException {
        count c = new count(1); //初始化count 设置i=1
        Runnable single = new singleRunnable(c);//创建一个线程类将count对象传入
        Runnable Double = new doubleRunnable(c);//创建一个线程类将count对象传入
        Thread tmp = new Thread(single);
        Thread tmp1 = new Thread(Double);
        tmp.start();//开始线程
        tmp1.start();//开始线程
    }

运行程序,结果如下:
这里写图片描述
咋看没有什么问题,线程1和线程2交替输出i的单双数。但是仔细看下发现程序一直没有结束还在运行,并且打印的j的值都为偶数。这就不对劲了。于是博主改变了count类中j的值,将j改成了奇数5。运行结果如下:
这里写图片描述
程序顺利执行完毕。后来又将j改成了3同样可以执行完毕。最后博主又将j改成几个偶数,结果跟第一次一样程序始终在执行。于是博主将j改成2跟随程序走了一遍发现了问题。
当两个线程启动时,i的初始值为1,flag=true。由于主函数中打印单数的线程在打印双数的线程前面进入准备状态,所以先执行print_single()函数。在print_single()中,输出i为1之后,i自增1变成2。将flag改为false,同时唤醒另一个打印双数的进程。但由于调用notify()函数后,被唤醒的线程不会马上执行,要等唤醒它的程序执行完或调用wait()后才会执行。所以print_single()函数在唤醒print_double()函数后还将继续执行,此时j自加变成1,然再判断flag,现在flag为false,所以调用wait()挂起。这时print_double()函数就开始执行了。print_double()开始执行时,j == 0,此时i==2。所以打印出的i和j分别为2,0。然后print_double()函数唤醒另一线程,同时继续执行。此时j变成1,i变成3,打印双数的线程执行wait()函数进入等待状态。等到print_single()函数开始执行时,j的值为1,从上次wait()函数停止的地方开始执行,所以j先自增变成2,判断条件不符后,结束该线程。而此时打印双数的线程任然在等待,并且由于没有notify()函数唤醒,将一直等待下去,所以就出现了我们之前看到的程序一直执行,以及打印出来的j的值都为偶数。
当我们把j的值换成奇数时,就可以正常执行完毕。
当我们在主程序中改变两个线程的启动顺序的时候即改成

public static void main(String[] args) throws IOException {
        count c = new count(1, 0);
        Runnable single = new singleRunnable(c);
        Runnable Double = new doubleRunnable(c);
        Thread tmp = new Thread(single);
        Thread tmp1 = new Thread(Double);


        //跟前面相比,交换了打印单双数线程的启动顺序
        tmp1.start();
        tmp.start();
        //--------------------------------

    }

j的值还是偶数时,这时程序也可以顺利执行完毕。
可以根据我分析第一种的方法,分析以上的两种情况。

3,总结

    由此我们可以发现,虽说多线程给我们的感觉是同时进行的,但是程序真正执行的时候还是有顺序之分的。将两线程启动顺序改变一下就会影响输出的结果。同时我们可以看出,wait()和notify()函数在本例子中作用的是一个对象中的不同方法,借此可以理解一下“wait(),notify()函数是作用在同步锁对象的线程上”这句话的含义。
完整代码如下:

import java.io.IOException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class count {
    private int i;

    //是否为单数
    private boolean flag = true;
    public count(int i) {
        this.i = i;
    }

    //打印单数
    public synchronized void print_single() throws InterruptedException {
        for(int j = 0; j < 2; j++) {
            if(flag) {
                System.out.println(Thread.currentThread().getName() + "---" + i + ",单数," + j);
                i++;
                flag = false;
                notify();
            } else {
                wait();
            }
        }
    }

    //打印双数
    public synchronized void print_double() throws InterruptedException {
        for(int j = 0; j < 2; j++) {
            if(flag) {
                wait();
            } else {
                System.out.println(Thread.currentThread().getName() + "---" + i + ",双数," + j);
                i++;
                flag = true;
                notify();
            }
        }
    }
}

class singleRunnable implements Runnable {
    private count c;

    public singleRunnable(count c) {
        this.c = c;
    }

    public void run() {
        try {
            c.print_single();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class doubleRunnable implements Runnable {
    private count c;

    public doubleRunnable(count c) {
        this.c = c;
    }

    public void run() {
        try {
            c.print_double();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

public class RunnableTest {
    public static void main(String[] args) throws IOException {
        count c = new count(1);
        Runnable single = new singleRunnable(c);
        Runnable Double = new doubleRunnable(c);
        Thread tmp = new Thread(single);
        Thread tmp1 = new Thread(Double);
        tmp.start();
        tmp1.start();
    }
}
浅谈java多线程wait,notify 主要介绍了java多线程wait,notify,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面小编和大家一起来学习一下吧 立即下载

相关推荐

用ST25DV芯片+KiCad快速设计NFC标签天线:参数计算/脚本生成/实测优化全流程

本文详细介绍了使用ST25DV芯片和KiCad工具设计NFC标签天线的全流程,包括参数计算、脚本生成和实测优化。通过解析芯片等效工作原理和设计思路,帮助开发者避开常见陷阱,实现高效、可量产的天线设计。文章还提供了Python计算工具和KiCad自动化脚本,大幅提升设计效率和成功率。

jj890的博客 756

【Java多线程编程】wait与notify方法详解

本期讲解:Java 多线程中的 wait方法、notify方法、notifyAll方法,wait方法与sleep方法之间的区别。

我的主页 4493

Halcon 3D视觉实战:5步将线激光高度数据转为可分析的深度图与点云

本文详细介绍了如何利用Halcon平台将线激光高度数据转换为深度图与点云的5步实战方法。通过具体代码示例和工业检测案例(如锂电池胶水测量),帮助工程师高效处理3D视觉数据,实现从原始数据到三维可视化的完整技术链路。

weixin_29039773的博客 361

Java多线程基础-7:wait() 和 notify() 用法解析

详解Java多线程编程中,wait()和notify()方法的使用方式和注意事项,配合代码案例~

wyd_333的博客 8413

C语言实现俄罗斯方块

使用C语言完成俄罗斯方块。《俄罗斯方块》的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。顾名思义,俄罗斯方块自然是俄罗斯人发明的。

qq_54169998的博客 7万+

【机器人学习】abb工业机器人运动学分析与圆弧轨迹规划(三维模型+matlab代码)

下载链接 solidworks模型 D-H建模 圆仿真过程 视频过程:

yjw0911的博客 2529

Java多线程wait()和notify()方法图解

多线程场景下 wait 和notify 方法详解,注意事项,内部阻塞队列和等待队列的过程,wait和sleep方法的区别

VIBE的博客 4248

Vivado与Vscode无缝集成:高效Verilog开发环境搭建指南

本文详细介绍了如何将Vivado与Vscode无缝集成,打造高效的Verilog开发环境。通过替换Vivado默认编辑器为Vscode,配置必备插件和语法检查工具,开发者可以大幅提升FPGA项目的编码效率。文章还提供了代码片段、Testbench自动生成等高级技巧,帮助开发者快速上手这一集成方案。

weixin_33737774的博客 493

JAVA多线程基础篇-线程通信(wait/notify)

在JAVA多线程中,线程通信是重要概念之一。线程通信能够使系统之间的交互性更强大,在大大提高CPU利用率的同时还会使程序员对各线程在任务处理过程中进行有效把控。本文将针对使用wait/notify进行线程之间通信进行分析,详述其实现过程、原理以及相关注意事项。.........

qq_33479841的博客 2301

SAP BAPI调用避坑指南:处理MD61/MD62计划独立需求时,这些参数和返回值你必须检查

本文详细解析了SAP BAPI调用中处理MD61/MD62计划独立需求的关键参数和返回值检查要点,包括版本控制、日期类型和删除标记等核心参数设置,以及常见错误排查和高级调试技巧,帮助开发者高效管理需求计划数据。

weixin_30316097的博客 610

MATLAB基础应用精讲-【深度强化学习】SAC(Soft Actor-Critic)算法(附MATLAB和python代码实现)

Actor 网络:用于选择动作。Critic 1 和 Critic 2 网络:用于估计 Q 值。Target Critic 1 和 Target Critic 2:与 Critic 网络架构相同,用于生成更稳定的目标 Q 值。,即在保证探索的情况下选择高价值动作。软更新目标 Q 网络参数,使得目标网络参数缓慢向当前网络靠近,避免振荡。

qq_36130719的博客 454

[Java 多线程技术](七)使用wait/notify实现线程间通信

线程是操作系统中独立的个体,但这些个体如果不经过特殊处理就不能成为一个整体。线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更加强大,在大大提高CPU利用率的同时还会使程序员对各线程任务在处理的过程中进行有效的把控和监督。 1. 等待通知机制 1.1 不使用等待/通知机制实现线程间通信   创建新项目,在实验中使用sleep()结合while(true)死循环法来实现多个线程间通信。代码如下: public class MyList { priva.

YHJ 2404

2026华为OD机试(C语言)真题【E卷+A卷+B卷+C卷+D卷】目录+在线OJ

华为OD机试真题题库【E卷+A卷+B卷+C卷+D卷】目录,C语言实现。

MISAYAONE的博客 11万+

多线程基础系列-多线程初识

多线程的初步介绍,包含 线程和进程、线程的状态、线程的创建

囚徒之困 1234

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java wait() notify()方法使用实例讲解

1)wait()、notify()和notifyAll()方法是本地方法,并且为final方法,无法被重写。   2)调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(即锁,或者叫管程)   3)调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程,如果有多个线程都在等待这个对象的monitor,则只能唤醒其中一个线程;

Java 之 道 4万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

深入理解Java多线程中的wait(),notify()和sleep()

大家在学习Java的过程中,势必要进行多线程的系统学习,这部分内容知识对于你在工作中的影响是极大的,并且在面试的过程中,这部分知识也是必然会被问到的。既然多线程的知识如此重要,那么我们就不能浅尝辄止。在这篇文章中,我想通过阅读源码的方式给大家分享一下我自己对于Java中wait(),notify()和sleep()的理解,并且在后面我也做一些内容上的扩展,与大家共同思考。如果在文章中有描述不妥或者

小游的博客 2万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

[小笔记] 理解 Java 中的 wait(),notify(),notifyAll() 等方法

相信很多人都有去看过这几个方法的描述,站在面试八股文的角度可能自认为学会了,我感觉很多人并没有真正理解这几个方法,我自己也是经常忘记😂,所以这次单独记录一下,以方便以后自己忘记了再回来查看。

m0_59162559的博客 1108

多线程编程-wait()与notify()

由于线程之间是抢占式执行的,因此线程之间的执行先后顺序总是难以预知的。但是实际开发中我们总是希望能够合理的协调多个线程之间的执行先后顺序。wait()/wait(long timeout):让当前的线程进入等待状态;notify()/notifyAll():唤醒当前的对象上等待的那个线程;wait()、wait(long timeout)、notify()、notifyAll()都是Object类的方法。

zcx777123的博客 1193

Java多线程 之 线程等待与唤醒 wait(), notify(),notifyAll()

文章目录1. wait(), notify(), notifyAll()等方法介绍2. wait()和notify()示例3. wait(long timeout)和notify()4. wait() 和 notifyAll()5. 为什么notify(), wait()等函数定义在Object中,而不是Thread中 1. wait(), notify(), notifyAll()等方法介绍  ...

萧曳丶 1854

详解Java线程中的wait()、notify()、notifyAll()方法

线程中的wait()、notify()、notifyAll()详解 在讲解wait()、notify()、notifyAll()方法之前,先了解一下什么是等待队列。所有的实例都拥有一个等待队列,它是在实例的wait方法执行后停止操作的线程的队列。打个比方就是为每一个实例准备的线程休息室。 在执行wait方法后,线程便会暂停操作,进入等待队列这个休息室,除非发生下列四种中的某一种情况,否则线程会一直在等待队列中休眠。 (1)有其他线程的notify方法来唤醒线程 (2)有其他线程的notifyAll方法来唤醒

Waiting的博客 2313

java多线程的wait(), notify(), notifyAll()的用法

参考博客: java wait()方法用法详解:https://www.jianshu.com/p/def7f016dd5e 你真的懂wait、notify和notifyAll吗:https://www.jianshu.com/p/25e243850bd2?appinstall=0 诡异的java.lang.IllegalMonitorStateException:https://blog.cs...

menghuanzhiming的博客 1668

wait()方法和notify()方法

由于操作系统对线程的调度是随机执行的,且线程之间是抢占式执行的,因此线程之间执行的先后顺序难以预知。但是,有时候在实际开发中,我们希望合理的协调多个线程之间的先后执行顺序。在Java中,wait()方法和notify()方法就是解决该问题的。

2302_80826557的博客 1118

Java多线程:Thread的使用,以及wait(),notify(),notifyAll()

本文章是Java多线程系列的一篇文章,其他文章: Java多线程:锁的底层实现 Java多线程:synchronized和volatile Java多线程:JUC包-锁的封装 Java多线程:Thread的使用,以及wait(),notify(),notifyAll() Java多线程:线程池 一、Thread的状态 在Thread类的1750行左右定...

spawpaw的博客 1078

【Java笔记】wait()、notify() / notifyAll()、join() 和 sleep()

解读 wait()、notify() / notifyAll()、join() 和 sleep()

Origin_life的博客 800

java多线程什么时候释放锁—wait()、notify()

由于等待一个锁定线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不需要锁的时候及时释放锁是很重要的。在以下情况下,持有锁的线程会释放锁: 1. 执行完同步代码块。 2. 在执行同步代码块的过程中,遇到异常而导致线程终止。 3. 在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进行对象的等待池。 除了以上情况外,只要持有锁...

benbenxiongyuan的专栏 1834

【多线程初阶】wait() & notify()

wait()与sleep和join的区别 & notify() & notifyAll() & 协调多个线程之间的执行顺序

2503_90322569的博客 928
上一篇: python引用同一包中其他.py文件的类
下一篇: 使用pip卸载包时出现“Not uninstalling *** at /usr/lib/python2.7/dist-packages, owned by OS解决”
TYOUKAI_
博客等级 码龄9年 33粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值