• Java马士兵高并发编程视频学习笔记(二)


    1.ReentrantLock的简单使用  

    Reentrant n.再进入

    ReentrantLock 一个可重入互斥Lock具有与使用synchronized方法和语句访问的隐式监视锁相同的基本行为和语义,但具有扩展功能。(从jdk1.8中文版复制而来)

    可以完成synchronized相同的作用,但必须手动释放锁

    package com.dingyu2;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * Reentrant n.再进入
     * ReentrantLock 一个可重入互斥Lock具有与使用synchronized方法和语句访问的隐式监视锁相同的基本行为和语义,但具有扩展功能。(从jdk1.8中文版复制而来)
     * 可以完成synchronized相同的作用,但必须手动释放锁
     * @author dingyu
     *
     */
    public class ReentrantLock1 {
        private Lock lock = new ReentrantLock();
    
        public void m1() {
            try {
                lock.lock();//synchronized(this)类似,锁定的是堆的对象
                for (int i = 0; i < 10; i++)
                    System.out.println("m1-" + i);
            } catch (Exception e) {
                System.out.println("m1启动");
    
            } finally {
                System.out.println("m1结束");
                lock.unlock();
            }
        }
    
        public void m2() {
            try {
                lock.lock();
                for (int i = 0; i < 10; i++)
                    System.out.println("m2-" + i);
    
            } catch (Exception e) {
                System.out.println("m2启动");
    
            } finally {
                System.out.println("m2结束");
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            ReentrantLock1 reentrantLock1 = new ReentrantLock1();
            new Thread(() -> reentrantLock1.m1()).start();
            new Thread(() -> reentrantLock1.m2()).start();
        }
    }

    2.ReentrantLock对synchronized的扩展之tryLock()

    package com.dingyu2;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * ReentrantLock对synchronized的扩展之tryLock()
     * 
     * @author dingyu
     *
     */
    public class ReentrantLock2 {
        private Lock lock = new ReentrantLock();
    
        public void m1() {
            lock.lock();// 一直锁着,不手动释放, 和synchronized(this)类似,锁定的是堆的对象
        }
    
        public void m2() {
            boolean isNotLock = lock.tryLock();// 如果别的进程锁着就返回false,如果没锁返回true
            // 我们可以根据有没有锁来执行自己的逻辑,而不需要等着锁的释放,更加灵活
            if (isNotLock) {
                System.out.println("lock对象没有被锁定");
            } else {
                System.out.println("lock对象被锁定了");
            }
        }
    
        public static void main(String[] args) {
            ReentrantLock2 reentrantLock2 = new ReentrantLock2();
            new Thread(() -> reentrantLock2.m1()).start();
            new Thread(() -> reentrantLock2.m2()).start();
        }
    }

    3.ReentranLock对synchronized的扩展:可以被另外的线程打断

    package com.dingyu2;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * ReentranLock对synchronized的扩展:可以被另外的线程打断
     * 因为m1方法一直占着锁,m2永远不可能得到锁,既然得不到锁,我们就关闭m2好了,这时候得用lockInterruptibly
     * 
     * @author dingyu
     *
     */
    public class ReentrantLock3 {
        private Lock lock = new ReentrantLock();
    
        public void m1() {
            lock.lock();
            try {
                System.out.println("t1 start");
                while (true) {
                }
            } finally {
                lock.unlock();
                System.out.println("t1 end");
            }
        }
    
        public void m2() {
            try {
                lock.lockInterruptibly();
                System.out.println("t2 start");
            } catch (InterruptedException e) {
                System.out.println("t2被打断了");
            } finally {
                if (lock.tryLock())
                    lock.unlock();
                System.out.println("t2 end");
            }
        }
    
        public static void main(String[] args) {
            ReentrantLock3 reentrantLock3 = new ReentrantLock3();
            Thread t1 = new Thread(() -> reentrantLock3.m1(), "t1");
            t1.start();
            Thread t2 = new Thread(() -> reentrantLock3.m2(), "t2");
            t2.start();
            t2.interrupt();
        }
    }

    4.ReentrantLock对synchronized的扩展 : 可以指定公平锁

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * ReentrantLock对synchronized的扩展 : 可以指定公平锁,哪个线程等待时间长,哪个先执行
     * 在构造函数中放入ture参数
     * 
     * @author dingyu
     *
     */
    public class ReentrantLock4 {
        private Lock lock = new ReentrantLock(true);
    
        public void m1() {
            for (int i = 0; i < 10; i++) {
                try {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + "running");
                } finally {
                    lock.unlock();
                }
            }
        }
        
        public static void main(String[] args) {
            ReentrantLock4 lock4 = new ReentrantLock4();
            new Thread(()->lock4.m1(),"t1").start();
            new Thread(()->lock4.m1(),"t2").start();
        }
    }

    5.使用wait和notifyAll实现消费者生产者模式

    package com.dingyu2;
    
    import java.util.LinkedList;
    
    /**
     * 使用wait和notifyAll实现消费者生产者模式
     * 
     * @author dingyu
     *
     */
    public class ProduceConsumer {
        private final LinkedList<Integer> lists = new LinkedList<Integer>();
        private final int MAX = 10;
        private int count = 0;
    
        public synchronized void put(Integer i) {
            while (lists.size() == MAX) { // wait大多数情况和while一起用
                try {
                    this.wait();// 如果满了我就释放锁,并且等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            lists.add(i);// 生产一个
            count++;
            this.notifyAll();// 叫醒消费者可以消费啦
        }
    
        public synchronized Integer get() {
            while (lists.size() == 0) {
                try {
                    this.wait();// 如果集合为空,不能消费,释放锁,等着
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Integer num = lists.removeFirst();
            count--;
            this.notifyAll();// 叫醒生产者,可以继续生产啦
            return num;
        }
    
    }

    6.使用Condition 完成生产者消费者模式

    package com.dingyu2;
    /**
     * 使用Condition 完成生产者消费者模式
     * @author dingyu
     *
     */
    
    import java.util.LinkedList;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ProduceConsumer2 {
        private final LinkedList<Integer> lists = new LinkedList<Integer>();
        private final int MAX = 10;
        private int count = 0;
    
        private Lock lock = new ReentrantLock();
        private Condition p = lock.newCondition();// 生产者
        private Condition c = lock.newCondition();// 消费者
    
        public void put(Integer i) {
            try {
                lock.lock();
                while (lists.size() == MAX) {
                    try {
                        p.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                lists.add(i);
                count++;
                c.signalAll();
            } finally {
                lock.unlock();
            }
        }
    
        public Integer get() {
            Integer i = null;
            try {
                lock.lock();
                while (lists.size() == 0) {
                    try {
                        c.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                i = lists.removeFirst();
                count++;
                p.signalAll();
            } finally {
                lock.unlock();
            }
            return i;
        }
    
    }

     7.ThreadLocal 线程局部变量  每个线程中的这个变量归自己线程管

    package com.dingyu;
    
    public class ThreadLocal1 {
        private ThreadLocal<Integer> tl = new ThreadLocal<Integer>();
    
        public void m1() {
            System.out.println(tl.get());
        }
    
        public void m2() {
            tl.set(7898);
        }
    
        public static void main(String[] args) {
            ThreadLocal1 local1 = new ThreadLocal1();
            new Thread(() -> local1.m2()).start();
    
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(() -> local1.m1()).start();
        }
    }
  • 相关阅读:
    找球号(一)
    拦截导弹
    开灯问题
    超级台阶
    小学生算术
    Financial Management
    三角形面积
    另一种阶乘问题
    并发环境下,先操作数据库还是先操作缓存?
    Flask框架Server和RequestHandler的爱恨纠缠
  • 原文地址:https://www.cnblogs.com/dddyyy/p/9975838.html
Copyright © 2020-2023  润新知