zoukankan      html  css  js  c++  java
  • 同步机制Lock初学

    前段时间review同事的代码,发现可以简化成如下的模型:

    Thread 1 Thread 2
    lock.lock();
    condition.await();
    lock.unlock()
    lock.lock();
    condition.signal();
    lock.unlock();

    怀疑是个死锁。写了下面这个case模拟了一下,却没有问题。

    但是T2为何能进入signal呢?

    根据javadoc的文档,这明显是第三种情况:

    public void lock()
    Acquires the lock.

    Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.

    If the current thread already holds the lock then the hold count is incremented by one and the method returns immediately.

    If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired, at which time the lock hold count is set to one.

    原来是因为T1进入await了,那么这个条件上的lock就自动释放了,文档如下:

    void await()
               throws InterruptedException

    Causes the current thread to wait until it is signalled or interrupted.

    The lock associated with this Condition is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

    代码如下:

    import java.util.Date;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

    public class LockTest {

        Lock lock = new ReentrantLock();
        Condition finishCondition = lock.newCondition();

        class T1 implements Runnable {

            public void run() {
                try {
                    lock.lock();
                    System.out.println("enter T1:" + new Date());
                    try {
                        finishCondition.await();
                        System.out.println("end wating T1:" + new Date());
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                } finally {
                    lock.unlock();
                    System.out.println("exit T1:" + new Date());
                }

            }

        }

        class T2 implements Runnable {

            public void run() {
                try {
                    lock.lock();
                    System.out.println("enter T2:" + new Date());
                    try {
                        Thread.sleep(1000);
                        finishCondition.signal();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                } finally {
                    lock.unlock();
                    System.out.println("exit T2:" + new Date());
                }
            }
        }

        public void run() throws Exception {
            new Thread(new T1()).start();
            Thread.sleep(50);
            new Thread(new T2()).start();
        }

        public static void main(String[] args) throws Exception {
            LockTest lt = new LockTest();
            lt.run();
            Thread.sleep(3000);
            System.out.println("exit main.");
        }

    }

  • 相关阅读:
    微软不也是从Altair Basic这丑小鸭长成白天鹅吗?
    互联网创业应该如何找到创意
    互联网创业创意养成记1
    安卓CTS官方文档之兼容性方案概览
    跨平台移动应用开发是否真的是一个好选择?
    Ubuntu安装MyEclise16 过程差不多
    Ubantu下安装jdk 教程
    最近出错总结
    使用Eclipse编译运行MapReduce程序 Hadoop2.6.0_Ubuntu/CentOS
    关于最近学习出现的错误,及解决的想法
  • 原文地址:https://www.cnblogs.com/alphablox/p/2858264.html
Copyright © 2011-2022 走看看