第四章-java多线程核心技术-Lock锁-第三篇

Condition实现顺序运行

使用condition对象能够对线程业务进行规划和排序。请看以下代码java

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

public class Run {
    volatile private static int nextPrintWho = 1;
    private static ReentrantLock lock = new ReentrantLock();
    final private static Condition conditionA = lock.newCondition();
    final private static Condition conditionB = lock.newCondition();
    final private static Condition conditionC = lock.newCondition();

    public static void main(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    lock.lock();
                    while (nextPrintWho != 1) {
                        conditionA.await();
                    }

                    for (int i = 0; i < 3; i++) {
                        System.out.println("printA is " + i);
                    }
                    nextPrintWho = 2;
                    conditionB.signalAll();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread threadb = new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    lock.lock();
                    while (nextPrintWho != 2) {
                        conditionB.await();
                    }

                    for (int i = 0; i < 3; i++) {
                        System.out.println("printB is " + i);
                    }
                    nextPrintWho = 3;
                    conditionC.signalAll();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread threadc = new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    lock.lock();
                    while (nextPrintWho != 3) {
                        conditionC.await();
                    }

                    for (int i = 0; i < 3; i++) {
                        System.out.println("printC is " + i);
                    }
                    nextPrintWho = 1;
                    conditionB.signalAll();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };
        Thread[] aArray = new Thread[10];
        Thread[] bArray = new Thread[10];
        Thread[] cArray = new Thread[10];

        for (int i =0 ;i <5 ;i++) {
            aArray[i] = new Thread(thread);
            bArray[i] = new Thread(threadb);
            cArray[i] = new Thread(threadc);
            aArray[i].start();
            bArray[i].start();
            cArray[i].start();
        }
    }
}

输出结果安全

printA is 0
printA is 1
printA is 2
printB is 0
printB is 1
printB is 2
printC is 0
printC is 1
printC is 2
printA is 0
printA is 1
printA is 2
printB is 0
printB is 1
printB is 2
printC is 0
printC is 1
printC is 2
printA is 0
printA is 1
printA is 2
printB is 0
printB is 1
printB is 2
printC is 0
printC is 1
printC is 2

读写锁的产生

ReentrantLock锁是彻底互斥的锁,即同一时间内只有一个线程执行锁后面的方法,这样作虽然保证了变量的线程安全性,可是效果是很是低下的。因此jdk提供了一种读写锁,在某些不须要操做gong共享变量的状况下彻底能够使用读写锁来提高方法的运行速度。ide

读写锁包含了两个锁,一个是读锁,也称共享锁,一个是写锁,也称排他锁。即多个读锁之间不互斥,写锁和读锁互斥,读锁和读锁互斥。在没有线程执行写入操做的时候,进行读取操做的多个线程均可以获取读锁,写锁只有在得到锁后才能进行写操做。this

读读共享

请看以下代码线程

public class ReadLock {
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public void read() {
        try {
            readWriteLock.readLock().lock();
            System.out.println("得到锁---->线程名称是---->"+Thread.currentThread().getName());
            Thread.sleep(1000);
            System.out.println("睡眠苏醒---->线程名称是---->"+Thread.currentThread().getName());
        } catch (InterruptedException ex){
            ex.printStackTrace();
        }finally {
            readWriteLock.readLock().unlock();
        }
    }
}

public class ThreadA extends Thread{
    private  ReadLock readLock ;

    public ThreadA(ReadLock readLock) {
        this.readLock = readLock;
    }

    @Override
    public void run() {
        readLock.read();
    }
}


public class ThreadB extends Thread{
    private  ReadLock readLock ;

    public ThreadB(ReadLock readLock) {
        this.readLock = readLock;
    }

    @Override
    public void run() {
        readLock.read();
    }
}

public class Run {
    public static void main(String[] args) {
        ReadLock lock = new ReadLock();
        ThreadA threadA = new ThreadA(lock);
        threadA.setName("A");
        ThreadB threadB = new ThreadB(lock);
        threadB.setName("B");
        threadA.start();
        threadB.start();
    }
}

输出结果是code

得到锁---->线程名称是---->B
得到锁---->线程名称是---->A
睡眠苏醒---->线程名称是---->B
睡眠苏醒---->线程名称是---->A

写写互斥

稍微修改上面的代码对象

public class WriteLock {
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public void read() {
        try {
            readWriteLock.writeLock().lock();
            System.out.println("得到锁---->线程名称是---->"+Thread.currentThread().getName());
            Thread.sleep(1000);
            System.out.println("睡眠苏醒---->线程名称是---->"+Thread.currentThread().getName());
        } catch (InterruptedException ex){
            ex.printStackTrace();
        }finally {
            readWriteLock.writeLock().unlock();
        }
    }
}

输出结果排序

得到锁---->线程名称是---->A
睡眠苏醒---->线程名称是---->A
得到锁---->线程名称是---->B
睡眠苏醒---->线程名称是---->B

读写互斥

请参考以下代码get

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLock {
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public void read() {
        try {
            readWriteLock.readLock().lock();
            System.out.println("读线程得到锁---->线程名称是---->" + Thread.currentThread().getName());
            Thread.sleep(1000);
            System.out.println("读线程睡眠苏醒---->线程名称是---->" + Thread.currentThread().getName());
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }
    }

    public void write() {
        try {
            readWriteLock.writeLock().lock();
            System.out.println("写线程得到锁---->线程名称是---->" + Thread.currentThread().getName());
            Thread.sleep(1000);
            System.out.println("写线程睡眠苏醒---->线程名称是---->" + Thread.currentThread().getName());
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }
}

public class ThreadA extends Thread{
    private ReadWriteLock readLock ;

    public ThreadA(ReadWriteLock readLock) {
        this.readLock = readLock;
    }

    @Override
    public void run() {
        readLock.read();
    }
}
public class ThreadB extends Thread{
    private ReadWriteLock readLock ;

    public ThreadB(ReadWriteLock readLock) {
        this.readLock = readLock;
    }

    @Override
    public void run() {
        readLock.write();
    }
}

public class Run {
    public static void main(String[] args) {
        ReadWriteLock lock = new ReadWriteLock();
        ThreadA threadA = new ThreadA(lock);
        threadA.setName("A");
        ThreadB threadB = new ThreadB(lock);
        threadB.setName("B");
        threadA.start();
        threadB.start();
    }
}

输出结果it

读线程得到锁---->线程名称是---->A
读线程睡眠苏醒---->线程名称是---->A
写线程得到锁---->线程名称是---->B
写线程睡眠苏醒---->线程名称是---->B
相关文章
相关标签/搜索