美文网首页
java 中Lock的使用【转】

java 中Lock的使用【转】

作者: KtYY | 来源:发表于2019-04-10 10:48 被阅读0次

    ReentrantLock也能够让代码块原子执行,但是比synchronized更加强大,ReentrantLock具有嗅探锁定、多路分支通知等功能。
    嗅探锁定:是指获取锁时如果锁已经被其他线程获取到ReentrantLock可以进行指定等待时间获取锁或者
    多路分支通知:是指线程发生await时,线程可以选择注册在不同的监视器Condition对象上,在适当的时候可以选择指定的监视器Condition对象上的线程进行signal通知、执行
    1、多线程执行同一代码块互斥

    import java.util.concurrent.locks.ReentrantLock;
    
    class MyService {
    
        private ReentrantLock lock = new ReentrantLock();
    
        public void method() {
            try {
                lock.lock();
                for (int i = 1; i <= 3; i++) {
                    Thread.sleep(1000);
                    System.out.println("ThreadName=" + Thread.currentThread().getName() + "  " + i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }
    
    class MyThread extends Thread {
    
        private MyService service;
    
        MyThread(MyService service) {
            this.service = service;
        }
    
        @Override
        public void run() {
            service.method();
        }
    }
    
    public class Test {
    
        public static void main(String[] args) {
            MyService service = new MyService();
            MyThread myThread1 = new MyThread(service);
            MyThread myThread2 = new MyThread(service);
    
            myThread1.start();
            myThread2.start();
        }
    }
    

    结果

    ThreadName=Thread-0 1
    ThreadName=Thread-0 2
    ThreadName=Thread-0 3
    ThreadName=Thread-1 1
    ThreadName=Thread-1 2
    ThreadName=Thread-1 3
    

    2、多线程执行不同代码块互斥

    import java.util.concurrent.locks.ReentrantLock;
    
    class MyService {
        private ReentrantLock lock = new ReentrantLock();
    
        public void methodA() {
            lock.lock();
            try {
                System.out.println("MethodA begin ThreadName=" + Thread.currentThread().getName());
                for (int i = 1; i <= 3; i++) {
                    System.out.println("ThreadName=" + Thread.currentThread().getName() + "  " + i);
                    Thread.sleep(1000);
                }
                System.out.println("MethodA end ThreadName=" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void methodB() {
            lock.lock();
            try {
                System.out.println("MethodB begin ThreadName=" + Thread.currentThread().getName());
                for (int i = 1; i <= 3; i++) {
                    System.out.println("ThreadName=" + Thread.currentThread().getName() + "  " + i);
                    Thread.sleep(1000);
                }
                System.out.println("MethodB end ThreadName=" + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
    
    class ThreadA extends Thread {
    
        private MyService service;
    
        ThreadA(MyService service) {
            this.service = service;
        }
    
        @Override
        public void run() {
            service.methodA();
        }
    }
    
    class ThreadB extends Thread {
    
        private MyService service;
    
        ThreadB(MyService service) {
            this.service = service;
        }
    
        @Override
        public void run() {
            service.methodB();
        }
    }
    
    public class Test {
    
        public static void main(String[] args) {
            MyService service = new MyService();
            ThreadA threadA = new ThreadA(service);
            threadA.setName("A");
    
            ThreadB threadB = new ThreadB(service);
            threadB.setName("B");
            threadA.start();
            threadB.start();
        }
    }
    

    结果:

    MethodA begin ThreadName=A
    ThreadName=A 1
    ThreadName=A 2
    ThreadName=A 3
    MethodA end ThreadName=A
    MethodB begin ThreadName=B
    ThreadName=B 1
    ThreadName=B 2
    ThreadName=B 3
    MethodB end ThreadName=B
    

    3、多路通知

    当多线程进入await状态时,利用Condition监视器对不同类型线程通知

    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    class MyService {
        private ReentrantLock lock = new ReentrantLock();
        private Condition conditionA = lock.newCondition();
        private Condition conditionB = lock.newCondition();
    
        public void methodA() {
            lock.lock();
            try {
                System.out.println("MethodA begin ThreadName=" + Thread.currentThread().getName() + "  " + System.currentTimeMillis());
                conditionA.await();
                System.out.println("MethodA end ThreadName=" + Thread.currentThread().getName() + "  " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void methodB() {
            lock.lock();
            try {
                System.out.println("MethodB begin ThreadName=" + Thread.currentThread().getName() + "  " + System.currentTimeMillis());
                conditionB.await();
                System.out.println("MethodB end ThreadName=" + Thread.currentThread().getName() + "  " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void signalA() {
            lock.lock();
            conditionA.signal();
            lock.unlock();
        }
        public void signalA_All() {
            lock.lock();
            conditionA.signalAll();
            lock.unlock();
        }
    
    
        public void signalB() {
            lock.lock();
            conditionB.signal();
            lock.unlock();
        }
        public void signalB_All() {
            lock.lock();
            conditionB.signalAll();
            lock.unlock();
        }
    }
    
    class ThreadA extends Thread {
    
        private MyService service;
    
        ThreadA(MyService service) {
            this.service = service;
        }
    
        @Override
        public void run() {
            service.methodA();
        }
    }
    
    class ThreadB extends Thread {
    
        private MyService service;
    
        ThreadB(MyService service) {
            this.service = service;
        }
    
        @Override
        public void run() {
            service.methodB();
        }
    }
    
    public class Test {
    
        public static void main(String[] args) throws InterruptedException {
            MyService service = new MyService();
            ThreadA threadA = new ThreadA(service);
            threadA.setName("A");
    
            ThreadB threadB = new ThreadB(service);
            threadB.setName("B");
            threadA.start();
            threadB.start();
    
            Thread.sleep(1000);
            service.signalA();
            Thread.sleep(1000);
            service.signalB();
    
    //        ThreadA[] threadAs = new ThreadA[10];
    //        for (int i=0;i<5;i++){
    //            threadAs[i] = new ThreadA(service);
    //        }
    //        ThreadB[] threadBs = new ThreadB[10];
    //        for (int i=0;i<5;i++){
    //            threadBs[i] = new ThreadB(service);
    //        }
    //
    //        for (int i=0;i<5;i++){
    //            threadAs[i].start();
    //            threadBs[i].start();
    //        }
    //
    //        Thread.sleep(1000);
    //        service.signalA_All();
    //        Thread.sleep(1000);
    //        service.signalB_All();
        }
    }
    

    测试结果1:

    MethodA begin ThreadName=A 1476800025028
    MethodB begin ThreadName=B 1476800025029
    MethodA end ThreadName=A 1476800026028
    MethodB end ThreadName=B 1476800027028
    

    修改代码为:

     public static void main(String[] args) throws InterruptedException {
            MyService service = new MyService();
    //        ThreadA threadA = new ThreadA(service);
    //        threadA.setName("A");
    //
    //        ThreadB threadB = new ThreadB(service);
    //        threadB.setName("B");
    //        threadA.start();
    //        threadB.start();
    //
    //        Thread.sleep(1000);
    //        service.signalA();
    //        Thread.sleep(1000);
    //        service.signalB();
    
            ThreadA[] threadAs = new ThreadA[10];
            for (int i=0;i<5;i++){
                threadAs[i] = new ThreadA(service);
            }
            ThreadB[] threadBs = new ThreadB[10];
            for (int i=0;i<5;i++){
                threadBs[i] = new ThreadB(service);
            }
    
            for (int i=0;i<5;i++){
                threadAs[i].start();
                threadBs[i].start();
            }
    
            Thread.sleep(1000);
            service.signalA_All();
            Thread.sleep(1000);
            service.signalB_All();
        }
    

    结果为:

    MethodA begin ThreadName=Thread-0 1476800227416
    MethodB begin ThreadName=Thread-7 1476800227417
    MethodB begin ThreadName=Thread-5 1476800227417
    MethodA begin ThreadName=Thread-3 1476800227418
    MethodA begin ThreadName=Thread-1 1476800227418
    MethodA begin ThreadName=Thread-4 1476800227418
    MethodB begin ThreadName=Thread-6 1476800227418
    MethodA begin ThreadName=Thread-2 1476800227418
    MethodB begin ThreadName=Thread-8 1476800227418
    MethodB begin ThreadName=Thread-9 1476800227418
    MethodA end ThreadName=Thread-0 1476800228419
    MethodA end ThreadName=Thread-3 1476800228419
    MethodA end ThreadName=Thread-1 1476800228419
    MethodA end ThreadName=Thread-4 1476800228420
    MethodA end ThreadName=Thread-2 1476800228420
    MethodB end ThreadName=Thread-7 1476800229419
    MethodB end ThreadName=Thread-5 1476800229419
    MethodB end ThreadName=Thread-6 1476800229419
    MethodB end ThreadName=Thread-8 1476800229419
    MethodB end ThreadName=Thread-9 1476800229419
    

    4、公平所与非公平锁
    公平锁是指线程获(getting)取锁的顺序和线程锁定(got)的顺序相同,

    Lock的一些方法说明
    A) getHoldCount()
    获取当前锁定(got)的个数
    B)getQueueLength()
    获取当前正在等待获取(getting)锁的线程数(Threads)
    C)getWaitQueueLength(Condition)
    返回等待(await)与此锁定(got)的Condition相关的个数

    原文:https://blog.csdn.net/jihaitaowangyi/article/details/52852693

    相关文章

      网友评论

          本文标题:java 中Lock的使用【转】

          本文链接:https://www.haomeiwen.com/subject/hdzgiqtx.html