JDK并发包--Condition,Semaphore,ReadWriteLock


ps:从北京到杭州可以有不同的路线,这些路线就好比多个线程,在路上可能因为各种原因停停走走,这就好比是线程的等待和通知。
Condition条件:
    使用sychronized关键字来保证线程的同步时,需要wait()和notify()来保证线程间的通信;而使用重入锁时,则需要通过Condition来使线程等待和继续执行。
    await(): 使当前线程等待,同时释放当前锁,当在其他线程中使用signal()或者signalAll()方法时,线程会重新获得锁并继续执行。也可响应中断跳出等待,类似于Object.wait()方法。
    awaitUninterruptibly(): 与await()方法基本相同,但是它不会响应中断。
    signal(): 唤醒一个等待中的进程。
    signalAll():唤醒所有等待中的进程。

public class LockCondition  implements Runnable{
    //锁的声明
    public static ReentrantLock lock = new ReentrantLock();
    public static Condition condition = lock.newCondition();

    @Override
    public void run(){
        try{
            lock.lock();    //和object.wait()类似,在执行await()前,需要线程持有相关重入锁
            condition.await();
            System.out.println("Thread is going on ");
        }catch(InterruptedException e){

        }finally{
            lock.unlock();
        }
    }
    public static void main(){
        LockCondition t1 =new LockCondition();
        Thread t = new Thread(t1);
        t.start();
        Thread.sleep(10000);
        lock.lock();    //和object.notify()类似,在执行signal()前,需要线程持有相关重入锁
        condition.signal();
        lock.unlock();
    }
}


信号量(Semaphore):
    允许多个线程同时访问临界区资源。
    public Semaphore(int permits);//传入一个整型值,表示同时允许访问的线程数。
    public Semaphore(int permits,boolean fair)//指定是否公平

    信号量的主要方法有:
    public void acquire();//获得一个准入许可
    public void acquireUninterruptibly();获得一个准入许可,但不响应中断
    public boolean tryAcquire();尝试获得许可,成功返回true,失败返回false;
    public boolean tryAcquire(long timout,TimeUnit unit);在时限内尝试获得许可
    public void release();线程访问资源结束后 ,释放许可
    
读写锁(ReadWriteLock)
    读操作和写操作之间相互阻塞,写操作和写操作之间相互阻塞,读操作和读操作之间不阻塞。下例启动了18个读线程,2个写线程,可以分别使用普通锁和读写锁,可以从结果看出读写锁耗时要远远低于普通锁

public class ReadWriteLockDemo {
    private static Lock lock = new ReentrantLock();
    private static ReentrantReadWriteLock readWriteLock =new ReentrantReadWriteLock();
    private static Lock readLock = readWriteLock.readLock();        //声明读锁
    private static Lock writeLock = readWriteLock.writeLock();        //声明写锁
    private int value;
    public Object handleRead(Lock lock) throws InterruptedException {
        try {
            lock.lock();
            Thread.sleep(1000);
            return value;
        }finally {
            lock.unlock();
        }
    }
    public void handleWrite(Lock lock,int index) throws InterruptedException {
        try {
            lock.lock();
            Thread.sleep(1000);
            value = index;
        }finally {
            lock.unlock();
        }
    }
    public static void main(String[] args) {
        final ReadWriteLockDemo demo = new ReadWriteLockDemo();
        
        Runnable readRunnable = new Runnable() {
            public void run() {
                try {
                    demo.handleRead(readLock);    //使用读写锁
                    //demo.handleRead(lock);    //使用普通锁
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Runnable writeRunnable = new Runnable() {
            public void run() {
                try {
                    demo.handleWrite(writeLock,new Random().nextInt());    //使用读写锁
                    //demo.handleRead(lock,new Random().nextInt());        //使用普通锁
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        
        for(int i=0;i<18;i++) {
            new Thread(readRunnable).start();
        }
        for(int i=18;i<20;i++) {
            new Thread(writeRunnable).start();
        }
    }
}

-----------------------------------------------------《实战Java高并发设计》笔记------------------------------------------------------