码迷,mamicode.com
首页 > 编程语言 > 详细

java 锁3

时间:2014-07-14 21:31:55      阅读:337      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   java   color   使用   

Object 有提供 三个重构的wait、一个notify、一个notifAll 。 都是线程或者说多线程,相关的。

Wait()方法,使当前获得指定对象锁的线程阻塞并释放锁。 ————我很好奇,为什么要阻塞,然后又释放呢?
Notify、NotifyAll 使当前没有获得指定对象锁的线程唤醒。

方法调用一定要处于synchronized关键字包含的代码中,即锁控制的区域。

package test;


public class ObjectLock {
    
    
    public static void main(String[] args) {

        final SimpleBean bean = new SimpleBean();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                bean.aa();
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                bean.bb();
            }
        });
        
        t1.start();
        try {
            Thread.sleep(100000);// sleep1
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t2.start();
        
    }

    
}

class SimpleBean {

    public synchronized void aa() {
        System.out.println("SimpleBean.aa() start !");
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("SimpleBean.aa() end !");
    }
    
    public synchronized  void bb() {
        System.out.println("SimpleBean.bb() 1");
        this.notify();
        System.out.println("SimpleBean.bb() 2");
    }
    
}

打印:
SimpleBean.aa() start !
SimpleBean.bb() 1
SimpleBean.bb() 2
SimpleBean.aa() end !


新建线程的sleep1时候的堆栈:

"Thread-0" prio=6 tid=0x02334400 nid=0x35fc in Object.wait() [0x047bf000..0x047bfb68]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x22e74c10> (a test.SimpleBean)
at java.lang.Object.wait(Object.java:485)
at test.SimpleBean.aa(ObjectLock.java:41)
- locked <0x22e74c10> (a test.SimpleBean)
at test.ObjectLock$1.run(ObjectLock.java:13)
at java.lang.Thread.run(Thread.java:619)

 

名称: Thread-0
状态:WAITING 在 test.SimpleBean@1f4cbee 上
阻塞总数:0 等待总数: 1

堆栈追踪:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:485)
test.SimpleBean.aa(ObjectLock.java:41)
test.ObjectLock$1.run(ObjectLock.java:13)
java.lang.Thread.run(Thread.java:619)

注:

wait抛出非runtime Exception, 必须捕获; notify 则不是。

wait、notify都必须被处于锁控制的区域,即一定要处于synchronized关键字或Lock的锁,包含的代码中。 否则就是 java.lang.IllegalMonitorStateException

参考 http://www.cnblogs.com/xwdreamer/archive/2012/05/12/2496843.html 

奇怪的是这么一句: 即使你确实知道当前上下文线程确实拥有了对象锁,也不能将object.wait()这样的语句写在当前上下文中

如果改成这样:

package test;


public class ObjectLock {
    
    
    public static void main(String[] args) {

        final SimpleBean bean = new SimpleBean();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                bean.aa();
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                bean.bb();
            }
        });
        
        t1.start();
//        try {
//            Thread.sleep(100000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        t2.start();
        
    }

    
}

class SimpleBean {

    public synchronized void aa() {
        System.out.println("SimpleBean.aa() start !");
        try {
//            this.wait();
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("SimpleBean.aa() end !");
    }
    
    public synchronized void bb() {
        System.out.println("SimpleBean.bb() 1");
        this.notify();
        System.out.println("SimpleBean.bb() 2");
    }
    
}

 

 

"Thread-1" prio=6 tid=0x02283000 nid=0x2be4 waiting for monitor entry [0x0483f000..0x0483fce8]
java.lang.Thread.State: BLOCKED (on object monitor)
at test.SimpleBean.bb(ObjectLock.java:50)
- waiting to lock <0x229bdde8> (a test.SimpleBean)
at test.ObjectLock$2.run(ObjectLock.java:19)
at java.lang.Thread.run(Thread.java:619)

"Thread-0" prio=6 tid=0x02280c00 nid=0x3a7c waiting on condition [0x047af000..0x047afd68]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at test.SimpleBean.aa(ObjectLock.java:42)
- locked <0x229bdde8> (a test.SimpleBean)
at test.ObjectLock$1.run(ObjectLock.java:13)
at java.lang.Thread.run(Thread.java:619)

 

名称: Thread-0
状态: TIMED_WAITING
阻塞总数:0 等待总数: 1

堆栈追踪:
java.lang.Thread.sleep(Native Method)
test.SimpleBean.aa(ObjectLock.java:42)
- 已锁定 test.SimpleBean@d72200
test.ObjectLock$1.run(ObjectLock.java:13)
java.lang.Thread.run(Thread.java:619)

 

名称: Thread-1
状态:BLOCKED 在 test.SimpleBean@d72200 上,拥有者: Thread-0
阻塞总数:1 等待总数: 0

堆栈追踪:
test.SimpleBean.bb(ObjectLock.java:50)
test.ObjectLock$2.run(ObjectLock.java:19)
java.lang.Thread.run(Thread.java:619)

 

 

可以看到Wait 方法确实是释放了锁的? 使外层的synchronized失效?

释放对象监控器的所有权,直到另外一个线程通过notify或notifyAll来唤醒。。。 

 

 <br>wait() <br>JDk文档写道 <br><br>在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。 <br><span style="">当前线程必须拥有此对象监视器</span> 。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。

而且此方法应始终在循环中使用 ?? 

参考:http://www.360doc.com/content/12/1010/19/59141_240697086.shtml

 好难理解。。

http://blog.sina.com.cn/s/blog_5ffe533a0101iw25.html

 

wait、notify 等和synchronized的关系?

 

重点:

Object的wait、notify等方法是为了多线程之间协作而准备的!明白了这点,就不会有那么多纠结了吧.. !!

 

2 Thread的sleep、interrupt、suspend、close。。。

 

java 锁3,布布扣,bubuko.com

java 锁3

标签:style   blog   http   java   color   使用   

原文地址:http://www.cnblogs.com/FlyAway2013/p/3841994.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!