java 锁3

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 在 [email protected] 上
阻塞总数: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)
- 已锁定 [email protected]
test.ObjectLock$1.run(ObjectLock.java:13)
java.lang.Thread.run(Thread.java:619)

名称: Thread-1
状态:BLOCKED 在 [email protected] 上,拥有者: 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

时间: 2024-11-10 08:32:16

java 锁3的相关文章

java锁的种类以及辨析(转载)

java锁的种类以及辨析(一):自旋锁 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) .这些已经写好提供的锁为我们开发提供了便利,但是锁的具体性质以及类型却很少被提及.本系列文章将分析JAVA下常见的锁名称以及特性,为大家答疑解惑. 1.自旋锁 自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时 才能进入临界区.如下 01 public class SpinLock { 02  

java 锁!

问题:如何实现死锁. 关键: 1 两个线程ta.tb 2 两个对象a.b 3 ta拥有a的锁,同时在这个锁定的过程中,需要b的锁:tb拥有b的锁,同时在这个锁定的过程中,需要a的锁: 关键的实现难点是3, —— 所以说,死锁也不是那么容易出现的吧.. 实现方式synchronized.Lock 等等 死锁例子1  采用了不同类的两个对象. 原理是: 两个线程尝试进入同一个需要对象锁的方法 package basic.thread; public class DL { public static

java锁和同步

Java 语言设计中的一大创新就是:第一个把跨平台线程模型和锁模型应用到语言中去,Java 语言包括了跨线程的关键字synchronized 和 volatile,使用关键字和java类库就能够简单的实现线程间的同步.在简化与平台无关的并发程序开发时,它没有使并发程序的编写工作变得繁琐,反而使它变得更容易了. 在这一章,我们详细介绍锁的技术和概念,java中提供了两种锁,一个是使用关键字的锁,还有一种类库提供的锁. synchronized关键字锁 synchronized关键字能够作为函数的修

java 锁2

并发,其实是多线程才有的场景... java 多线程? 锁? 现在看来,即使已经工作了4.5年,这仍然不是一个简单的问题. 其实java 本身有提供锁的机制. 比如 Object对象的 wait .notify 方法.synchronized 的原理不过是直接调用对应的对象的 wait方法罢了! 看tomcat 源码的时候,多线程的地方就是直接用到了 wait .notify等方法 —— 这些方法真高级, 一般哪里会用得着???!!! 1 synchronized 其实这个算是容易学的东西了,相

Java 锁的学习

个人学习整理,所有资料均来源于网络,非原创. 死锁的四个必要条件:互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用.请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源.一个进程因请求资源而阻塞时,对已获得的资源保持不放.非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺.循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源. 不难看出

java锁Lock的应用

package jun.lock; public class BankCard { protected String cardId;//银行卡号 protected int balance = 8000;//余额 public String getCardId() { return cardId; } public void setCardId(String cardId) { this.cardId = cardId; } public int getBalance() { return ba

有关Java 锁原理

锁 锁是用来锁东西的,让别人打不开也看不到!在线程中,用这个“锁”隐喻来说明一个线程在“操作”一个目标(如一个变量)的时候,如果变量是被锁住的,那么其他线程就对这个目标既“操作”不了(挂起)也无法看到目标的内容!对Java并发包,锁的实现基本在java.util.concurrent.locks包中,说“基本”是因为,在java.util.concurrent中还有CountDownLatch(可以看成带计数器的锁),CyclicBarrier,Semaphore(类似于信号量,但是也可以看成一

Java锁(一)之内存模型

想要了解Java锁机制.引发的线程安全问题以及数据一致性问题,有必要了解内存模型,机理机制了解清楚了,这些问题也就应声而解了. 一.主内存和工作内存 Java内存模型分为主内存和工作内存,所有的变量都存储在主内存中.每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量.不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要主内存来完成. 二.线程.工作内存和主内存 下面是

java 锁4

关于锁的分类 及 锁的灵活使用: 参见 http://blog.csdn.net/qaz13177_58_/article/details/21543515  有几句话说得相当不错: 锁的分类 : 同步分为类级别和对象级别,分别对应着类锁和对象锁.类锁是每个类只有一个,如果static的方法被synchronized关键字修饰,则在这个方法被执行前必须获得类锁:对象锁类同. 唤醒的含义: 只要是在synchronied块中的代码,没有对象锁是寸步难行的.其实唤醒一个线程就是重新允许这个线程去获得