Java多线程-Lock的使用

Posted Alan Lau

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程-Lock的使用相关的知识,希望对你有一定的参考价值。

ReentrantLock类

在JDK1.5中,新增了 ReentrantLock,相比 synchronized 在扩展功能上更加强大,比如具有嗅探锁定、多路分支通知等功能。

示例:

 

public class Test {
    public static void main(String[] args) {
        MyService service = new MyService();
        new Thread(() -> service.methodA()).start();
        new Thread(() -> service.methodB()).start();
    }

    static class MyService {
        private Lock lock = new ReentrantLock();

        public void methodA() {
            lock.lock();
            try {
                System.out.println("methodA begin ThreadName = " + Thread.currentThread().getName() + " time = " + System.currentTimeMillis());
                Thread.sleep(5000);
                System.out.println("methodA end ThreadName = " + Thread.currentThread().getName() + " time = " + System.currentTimeMillis());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void methodB() {
            lock.lock();
            try {
                System.out.println("methodB begin ThreadName = " + Thread.currentThread().getName() + " time = " + System.currentTimeMillis());
                Thread.sleep(5000);
                System.out.println("methodB end ThreadName = " + Thread.currentThread().getName() + " time = " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}

运行结果如图:

 

 

使用Condition 实现等待/通知

public class ConditionTest {
    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();
        new Thread(() -> service.await()).start();
        Thread.sleep(3000);
        service.signal();
    }

    static class Service {
        private Lock lock = new ReentrantLock();
        private Condition condition = lock.newCondition();

        public void await() {
            lock.lock();
            try {
                System.out.println("begin await 时间为" + System.currentTimeMillis());
                condition.await();
                System.out.println("end await 时间为" + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void signal() {
            lock.lock();
            try {
                System.out.println("begin signal 时间为" + System.currentTimeMillis());
                condition.signal();
                System.out.println("end signal 时间为" + System.currentTimeMillis());
            } finally {
                lock.unlock();
            }
        }
    }
}

运行结果如图:

 

 

使用Condition实现多对多生产者/消费者模式

public class Test {
    public static void main(String[] args) {
        Service service = new Service();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < Integer.MAX_VALUE; j++) {
                    service.set();
                }
            }).start();
            new Thread(() -> {
                for (int j = 0; j < Integer.MAX_VALUE; j++) {
                    service.get();
                }
            }).start();
        }
    }

    static class Service {
        private Lock lock = new ReentrantLock();
        private Condition condition = lock.newCondition();
        private boolean hasValue = false;

        public void set() {
            lock.lock();
            try {
                while (hasValue == true) {
                    System.out.println("有可能++连续");
                    condition.await();
                }
                System.out.println("打印+");
                hasValue = true;
                condition.signalAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void get() {
            lock.lock();
            try {
                while (hasValue == false) {
                    System.out.println("有可能**连续");
                    condition.await();
                }
                System.out.println("打印*");
                hasValue = false;
                condition.signalAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}

运行结果如图:

 

以上是关于Java多线程-Lock的使用的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程与并发库高级应用-工具类介绍

Java多线程编程中的lock使用源码详解

Java多线程Lock

Java多线程 Lock接口,ReentranctLock,ReentrantReadWriteLock

Java多线程学习篇Lock

java学习第22天(关于java中的锁LOCK及多线程的面试题)