java的wait()方法使用注意事项

1.本文解决的问题

(1)wait()方法一定要使用sycronized进行同步吗?不用sycronized修饰会有什么问题?
(2)wait()方法会释放对象锁,那么这里指的锁是什么?
(3)wait()会释放对象锁,而sleep()不会释放对象锁,这在实际情况中有什么区别?

2.结论

(1)wait()一定要使用sycronized进行同步,否则会报“java.lang.IllegalMonitorStateException”异常。这是因为wait方法会释放对象锁,而此时因为没有用sycronized同步,就没有锁,就会报异常。
(2)锁指的是sycronized修饰的方法、对象、代码块,如下实例中的value。
(3)因为wait()释放了锁,故其他线程可以执行本来由sycronized修饰的内容。例如下面实例中的run()方法内打印value值(System.out.println(value);)。

3.实例

如下,我们首先新建自己的线程类,覆写run()方法,新线程的作用是判断传进来的值是不是”123”,如果是就等待10s,不是就修改传进来的值并打印出来。

public class MyThread extends Thread {
    StringBuilder value;
    public MyThread(StringBuilder value) {
        this.value = value;
    }
    @Override
    public void run() {
        try {
            synchronized(value) { 
                System.out.println(value);
                if ((value.toString()).equals("123")) {
                    System.out.println(getName() + "开始等待;当前时间秒数:" + Calendar.getInstance().get(Calendar.SECOND));
                    value.wait(10000);// 注意这里不是说让value进行wait,而是让当前线程进行wait
                } else {
                    value = value.append("2");
                    System.out.println("当前线程名:" + getName() + ";" + value );
                }
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

然后在主函数中新建三个自己定义的线程并运行:

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        StringBuilder value = new StringBuilder("123");
        MyThread myThread1 = new MyThread(value);
        MyThread myThread2 = new MyThread(value);
        MyThread myThread3 = new MyThread(value);
        myThread1.start();
        myThread2.start();
        myThread3.start();
    }

这个程序的执行结果为:

123
Thread-0开始等待;当前时间秒数:5
123
Thread-2开始等待;当前时间秒数:5
123
Thread-1开始等待;当前时间秒数:5

如果我们把MyThread类的第9行和第18行,也就是sycronized的修饰去掉,就会报“java.lang.IllegalMonitorStateException”异常。
如果我们把MyThread类的第13行的value.wait(10000)语句替换为sleep(10000),则输出如下:

123
Thread-1开始等待;当前时间秒数:5
123
Thread-0开始等待;当前时间秒数:15
123
Thread-2开始等待;当前时间秒数:25

由输出的时间秒数可见,使用sleep会使三个线程依此执行,一个等待完10s后另一个才会进入sycronized内进行等待。而使用wait,则三个线程基本都是一起开始等待的,也就是wait会释放对value的锁定,其他线程可以执行sycronized代码块中的语句。另外使用sleep并不一定非要同步,这里是为了验证sleep不会释放锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值