Java线程 wait() notity(),异常:IllegalMonitorStateException

本文通过实例解析wait(), notify(), notifyAll()在多线程中的使用,解决初学者困惑,包括方法调用方式、线程状态变化及并发影响。

简介:

         在学习线程时,对wait(),notity(),notityAll()方法的使用感觉很懵,所以自己动手写了一个例子去一探究竟,这里分享出来,希望能对初学者有所帮助

疑惑:

问题①:方法如何使用

问题②:线程在等待的时候如果操作还未执行完,其他线程给它释放锁之后,它的操作结果是什么

问题③:启动其他线程后,对自身操作有没有影响

案例代码



public class Demo2 {
    public Integer a = 1;


    public static void main(String[] args) throws InterruptedException {
        //模拟等待状态下,释放锁后数据的变化情况

        Demo2 demo2 = new Demo2();

        //线程一执行修改a
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (demo2){
                    System.out.println("进来时的a:"+demo2.a);
                    demo2.a = demo2.a+3;
                    try {
                        //等待
                        demo2.wait();
                    } catch (InterruptedException e) {
                        System.out.println("线程等待出错");
                    }
                    demo2.a++;
                    System.out.println("出去时a : "+demo2.a);

                }

                //验证释放锁后是否整个线程都在等待状态
                System.out.println("我其它操作还在执行吗?");



            }
        });
        thread1.start();

        //主线程休眠一下再开启下一个线程,防止并发,确保线程一先执行
        Thread.sleep(10);

        //线程二也执行修改int,然后打开所有休眠中的线程
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (demo2){
                    System.out.println("二 进来时a:"+demo2.a);
                    demo2.a = demo2.a-2;
                    //启动等待线程一
                    demo2.notify();
                    demo2.a++;

                    System.out.println("二 执行结束a:"+demo2.a);
                }
            }
        });
        thread2.start();
    }
}

初始使用时遇到错误:

        ①:java.long.IllegalMonitorStateException

        //当前线程没有调用wait()/notify()对象的锁

        解决:

                百度查询,该方法是对加锁对象进行调用,不是对线程进行调用

总结:

        ①:wait()释放当前对象的锁,并让当前线程进入等待状态,其他拥有该对象锁的线程调用notify()方法时,那个等待中的线程才会再次启动

        ②:线程释放锁后,不会保留先前的执行结果,再次获得锁之后,继续执行剩下的操作

        ③:其他线程开启另一个线程时,对自身不会造成影响

        理解:这个锁其实是在Demo2对象中的(jvm中的说法就是,在对象头中),所以是Demo2对象调用wait()方法,使自己的锁状态改成无锁状态,并把当前执行的加锁的线程进入等待状态,只有其他含有该对象锁的线程调用这个Demo2对象的notify()方法才能启动原先等待状态的线程,而那线程被释放后会继续来抢夺锁的所有权然后完成未完成的程序

        

以上就是小编的一些个人理解,如有不对的地方还望各位帮忙指出,谢谢

09-10 11:18:11.121 04902 05440 I SystemUi--Keyguard: PictorialWallpaperLoader-->processLoadWallpaperReq Filepath pictorial-inlay-resID:2131231843 09-10 11:18:11.122 07094 07094 D AntiTheftManager: USB connection set to Charging Only now. 09-10 11:18:11.122 02967 04752 D DisplayAdapterExt: sendDisplayDeviceEventLocked event=2,now=58130567,timestamp=58130567 device:[id=local:4630946996568193153,stack=-1],isFirst=true,activeMode=1,state=ON,commitState=OFF,devInfo:null 09-10 11:18:11.122 04902 04902 D SystemUi--Keyguard: KeyguardClockPositionAl-->ClockPosition, canScaleFadePanel:false, mPanelExpansion:1.0, originalPanelExpansion:1.0, finalPanelExpansion:1.0, usePanelAnimFraction:false, panelAnimFraction:1.0, mQsExpansion:0.0, isQsVisible:false, mUnlockedStackScrollerPadding:366, mKeyguardStatusHeight:385, mStatusViewBottomMargin:72, mMinTopMargin:264, clockY:264, userSwitchY:120, clockYFullyDozing:231, clockAlpha:1.0, stackScrollerPadding:649, stackScrollerPaddingExpanded:649, clockX:0, clockScale:1.0, emptyDragAmount:0.0, isSplitShade:false, hintRunning:false, isNotiWorkshopRun:false, notiTY:0 09-10 11:18:11.122 02967 04752 D OplusSmartBrightnessController: requestDisplayState isFirstDisplay=true state=2 globalDisplayState=0x2 09-10 11:18:11.122 02967 03011 D DisplayDeviceRepositoryExtImpl: onDisplayDeviceEvent event=2,now=58130567,timestamp=58130567 device:[id=local:4630946996568193153,stack=-1],isFirst=true,activeMode=1,state=ON,commitState=OFF,devInfo:null 09-10 11:18:11.122 02967 04752 D DisplayDeviceExt: setDisplayState([4630946996568193153,true],OFF->ON),t-Name=PhotonicModulator 09-10 11:18:11.122 01427 01427 I QTI PowerHAL: Power setMode: 7 to: 1 09-10 11:18:11.123 01591 01789 D nwatchcall: ignoreCaptrueAndReport 0 09-10 11:18:11.123 01591 01591 I OplusSurfaceFlinger: Setting power mode 2 on display 4630946996568193153, called from 2967 09-10 11:18:11.123 01591 01591 D SurfaceFlinger: Setting power mode 2 on display 4630946996568193153 09-10 11:18:11.123 02967 03011 I DisplayDeviceRepository: Display device changed state: "内置屏幕", ON 09-10 11:18:11.123 04902 04902 D SystemUi--Keyguard: OplusKeyguardGaiaManager-->onEvent(101316) start 09-10 11:18:11.123 04902 04902 I SystemUi--Keyguard: PictorialWallpaperHelper-->onScreenTurningOn 09-10 11:18:11.123 04902 04902 D SystemUi--Keyguard: LockDeadUtil-->sendScreenOnBroadcast() not support find phone occluded view! 09-10 11:18:11.123 02967 03008 D UsbDeviceManager: setEnabledFunctions [functions= ,forceRestart=false ,usbDataUnlocked=false ,mUsbDataUnlocked=false ,operationId=1005] 09-10 11:18:11.123 01591 01920 I OplusDEE: handleDEE: 0x00040001 09-10 11:18:11.124 02967 03008 D UsbDeviceManager: oplusFunctions: diag,adb 09-10 11:18:11.124 01591 01591 D SurfaceFlinger: setSchedFifo : enable = 1分析一下为什么设置了charging only后到底层还是传了diag,adb
最新发布
09-13
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值