我之见--线程ReentrantLock

本文介绍了Java 5中引入的Lock和Condition机制,探讨了它们如何提供更灵活的线程同步解决方案,相较于传统的synchronized关键字。文章通过示例代码详细解释了ReentrantLock及其配套的Condition对象的使用方法。

Java 5中提供了另一种实现线程同步或互斥的机制,即使用LockCondition

Lock比传统线程模型中的synchronized方式更加面向对象,也提供了更多可选择的锁机制。与生活中的锁类似,锁本身也是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须使用同一个Lock对象。

Condition 将 Object 监视器方法(waitnotify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用

条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样。

Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其newCondition() 方法。一个ReentrantLock可以new 出多个条件Condition:

     Lock lock = new ReentrantLock();
        
        Condition condition1 = lock.newCondition();
        
        Condition condition2 = lock.newCondition();
        
        Condition condition3 = lock.newCondition();
  下面我们来看 ReentrantLock相关api

void lock();
   获取锁。
   如果锁不可用,出于线程调度目的,将禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态。
  
void lockInterruptibly() throws InterruptedException;
   如果当前线程未被中断,则获取锁。如果锁可用,则获取锁,并立即返回。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下两种情况之一以前,该线程将一直处于休眠状态:
   锁由当前线程获得;或其他某个线程中断当前线程,并且支持对锁获取的中断。如果当前线程;在进入此方法时已经设置了该线程的中断状态;或者
   在获取锁时被中断,并且支持对锁获取的中断,则将抛出 InterruptedException,并清除当前线程的已中断状态。
   Condition newCondition();
  返回绑定到此 Lock 实例的新 Condition 实例。下一小节中会重点谈Condition,此处不做过多的介绍。

  boolean tryLock();
  仅在调用时锁为空闲状态才获取该锁。
  如果锁可用,则获取锁,并立即返回值 true。如果锁不可用,则此方法将立即返回值 false。
  通常对于那些不是必须获取锁的操作可能有用。

   boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
   如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。
  如果锁可用,则此方法将立即返回值 true。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下三种情况之一前,该线程将一直处于休眠状态:

  void unlock() <span style="font-family: simsun;">释放锁;</span>


下面我们也来看一下Condition api 

</pre></p><p style="margin-top: 0px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; line-height: 21px; font-family: simsun; text-indent: 28px;"><span style="font-size:18px;">signalAll:唤醒在此监视器上面的所有线程,</span></p><p style="margin-top: 0px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; line-height: 21px; font-family: simsun; text-indent: 28px;"><span style="font-size:18px;">signal:唤醒在此监视器上面的某一条线程,一般是随机的一条线程,</span></p><p style="margin-top: 0px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; line-height: 21px; font-family: simsun; text-indent: 28px;"><span style="font-size:18px;">await;等待和Object 的wait一样,</span></p><p style="margin-top: 0px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; line-height: 21px; font-family: simsun; text-indent: 28px;"><span style="font-size:18px;">await(time, unit);在一定的时间内等待和Object wait(time,unit)用法一样。</span></p><p style="margin-top: 0px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; line-height: 21px; font-family: simsun; text-indent: 28px;"></p><p style="margin-top: 0px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; line-height: 21px; font-family: simsun; text-indent: 28px;">下面我们来看一下使用实例:</p><p style="margin-top: 0px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; line-height: 21px; font-family: simsun; text-indent: 28px;"><pre name="code" class="java">package javaThread;

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

public class ConditionCommunication {

    /**
     * @param args
     */
    public static void main(String[] args) {

        final Business business = new Business();

        new Thread(new Runnable() {

            public void run() {
                for (int i = 0; i < 1; i++) {
                    business.sub2(i);
                }
            }

        }).start();

        new Thread(new Runnable() {

            public void run() {
                for (int i = 0; i < 1; i++) {
                    business.sub3(i);
                }
            }

        }).start();

        new Thread(new Runnable() {

            public void run() {
                for (int i = 0; i < 1; i++) {
                    business.main(i);
                }
            }

        }).start();

    }

    static class Business {

        private int shouldSub = 1;

        private Lock lock = new ReentrantLock();

        Condition condition1 = lock.newCondition();

        Condition condition2 = lock.newCondition();

        Condition condition3 = lock.newCondition();

        public void sub2(int i) {
            try {
                lock.lock();
                while (shouldSub != 2) {
                    try {
                        condition2.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                for (int j = 1; j <= 5; j++) {
                    System.out
                            .println("sub2 thread sequence is @@@@@@@@@@@@" + j + " loop of " + i);
                }
                shouldSub = 3;
                condition3.signal();
            } finally {
                lock.unlock();
            }
        }

        public void sub3(int i) {
            try {
                lock.lock();
                while (shouldSub != 3) {
                    try {
                        condition3.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                for (int j = 1; j <= 5; j++) {
                    System.out.println("sub3 thread sequence is #############" + j + " loop of "
                            + i);
                }
                shouldSub = 1;
                condition1.signal();
            } finally {
                lock.unlock();
            }
        }

        public void main(int i) {
            try {
                lock.lock();
                System.out.println("main thread sequence is $$$$$$$$$$$$ ^^"
                        + Thread.currentThread().getName());
                while (shouldSub != 1) {
                    try {
                        condition1.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                for (int j = 1; j <= 5; j++) {
                    System.out
                            .println("main thread sequence is $$$$$$$$$$$$" + j + " loop of " + i);
                }
                shouldSub = 2;
                condition2.signal();
                condition2.await(time, unit);
            } finally {
                lock.unlock();
            }
        }
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值