• Java 并发编程锁工具


    记录几个常用的并发编程锁工具和用法

    ReentrantLock

    重入锁:和synchronized可以重入,但必须手动释放防止死锁定

    public class TestReentrantLock extends Thread {
    		
    	private static ReentrantLock lock=new ReentrantLock(true); //参数为true表示为公平锁,请对比输出结果
        public void run() {
            for(int i=0; i<100; i++) {
                lock.lock();
                try{
                    System.out.println(Thread.currentThread().getName()+"获得锁");
                }finally{
                    lock.unlock();
                }
            }
        }
        public static void main(String[] args) {
            TestReentrantLock rl=new TestReentrantLock();
            Thread th1=new Thread(rl);
            Thread th2=new Thread(rl);
            th1.start();
            th2.start();
        }
    }
    

    CountDownLatch

    计数器:阻塞线程,直到计数器归零

    public class T06_TestCountDownLatch {
        public static void main(String[] args) {
            usingCountDownLatch();
        }
        private static void usingCountDownLatch(){
            Thread[] threads = new Thread[100];
            CountDownLatch latch = new CountDownLatch(threads.length);
            for (int i = 0; i < threads.length; i++) {
                threads[i] = new Thread(()->{
                    int result = 0;
                    for(int j=0;j<10000; j ++) result += j;
                    latch.countDown();
                });
            }
            for (int i = 0; i < threads.length; i++) {
                threads[i].start();
            }
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("end latch");
        }
    }
    

    CyclicBarrier

    栅栏,第一个参数可以设置一个值,第二个参数传实现Runnable的类,当值达到了以后,放倒栅栏进行,运行Runnable类实例对象的run()方法

    public class TestCyclicBarrier {
        public static void main(String[] args) {
            // 上20人后发车
            CyclicBarrier barrier = new CyclicBarrier(20, () -> System.out.println("满人,发车"));
            for (int i = 0; i < 100; i++) {
                int finalI = i;
                new Thread(()->{
                    try{
                        System.out.println("上车"+ finalI);
                        barrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }).start();
            }
        }
    }
    

    Phaser

    相位器: 可以分阶段执行
    例子:结婚(新郎 新娘 5个客人)
    阶段一:
    所有人到达,开始吃饭
    阶段二:
    所有人吃完,开始离开
    阶段三:
    所有人离开,新娘新郎洞房

    public class TestPhaser {
        static Random r = new Random();
        static MarriagePhaser phaser = new MarriagePhaser();
        static void milliSleep(int milli) {
            try {
                TimeUnit.MILLISECONDS.sleep(milli);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            phaser.bulkRegister(7);
            for(int i=0; i<5; i++) {
                new Thread(new Person("p" + i)).start();
            }
            new Thread(new Person("新郎")).start();
            new Thread(new Person("新娘")).start();
        }
        static class MarriagePhaser extends Phaser {
            @Override
            protected boolean onAdvance(int phase, int registeredParties) {
                switch (phase) {
                    case 0:
                        System.out.println("所有人到齐了!" + registeredParties);
                        System.out.println();
                        return false;
                    case 1:
                        System.out.println("所有人吃完了!" + registeredParties);
                        System.out.println();
                        return false;
                    case 2:
                        System.out.println("所有人离开了!" + registeredParties);
                        System.out.println();
                        return false;
                    case 3:
                        System.out.println("婚礼结束!新郎新娘抱抱!" + registeredParties);
                        return true;
                    default:
                        return true;
                }
            }
        }
        static class Person implements Runnable {
            String name;
            public Person(String name) {
                this.name = name;
            }
            public void arrive() {
                milliSleep(r.nextInt(1000));
                System.out.printf("%s 到达现场!
    ", name);
                phaser.arriveAndAwaitAdvance();
            }
            public void eat() {
                milliSleep(r.nextInt(1000));
                System.out.printf("%s 吃完!
    ", name);
                phaser.arriveAndAwaitAdvance();
            }
            public void leave() {
                milliSleep(r.nextInt(1000));
                System.out.printf("%s 离开!
    ", name);
                phaser.arriveAndAwaitAdvance();
            }
            private void hug() {
                if(name.equals("新郎") || name.equals("新娘")) {
                    milliSleep(r.nextInt(1000));
                    System.out.printf("%s 洞房!
    ", name);
                    phaser.arriveAndAwaitAdvance();
                } else {
                    phaser.arriveAndDeregister();
                    //phaser.register()
                }
            }
            @Override
            public void run() {
                arrive();
                eat();
                leave();
                hug();
            }
        }
    }
    

    ReadWriteLock

    读写锁:读多写少的情况,读锁排写不排读,写锁是排他的

    public class TestReadWriteLock {
        static Lock lock = new ReentrantLock();
        private static int value;
        static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        static Lock readLock = readWriteLock.readLock();
        static Lock writeLock = readWriteLock.writeLock();
        public static void read(Lock lock) {
            try {
                lock.lock();
                Thread.sleep(1000);
                System.out.println("read over!");
                //模拟读取操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
        public static void write(Lock lock, int v) {
            try {
                lock.lock();
                Thread.sleep(1000);
                value = v;
                System.out.println("write over!");
                //模拟写操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            //Runnable readR = ()-> read(lock);
            Runnable readR = ()-> read(readLock);
            //Runnable writeR = ()->write(lock, new Random().nextInt());
            Runnable writeR = ()->write(writeLock, new Random().nextInt());
            for(int i=0; i<18; i++) new Thread(readR).start();
            for(int i=0; i<2; i++) new Thread(writeR).start();
        }
    }
    

    Semaphore

    信号量:可以控制同一时间有几个线程在执行

    public class TestSemaphore {
        public static void main(String[] args) {
        //Semaphore s = new Semaphore(2);
        Semaphore s = new Semaphore(2, true);
        //允许一个线程同时执行
        //Semaphore s = new Semaphore(1);
        new Thread(()->{
            try {
                s.acquire();
                System.out.println("T1 running...");
                Thread.sleep(200);
                System.out.println("T1 running...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                s.release();
            }
        }).start();
        new Thread(()->{
            try {
                s.acquire();
                System.out.println("T2 running...");
                Thread.sleep(200);
                System.out.println("T2 running...");
                s.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
    }
    

    Exchanger

    交换:将两个线程阻塞,交换变量,

    public class TestExchanger {
        static Exchanger<String> exchanger = new Exchanger<>();
        public static void main(String[] args) {
            new Thread(() -> {
                String s = "T1";
                try {
                    s = exchanger.exchange(s);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " " + s);
            }, "t1").start();
            new Thread(() -> {
                String s = "T2";
                try {
                    s = exchanger.exchange(s);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " " + s);
            }, "t2").start();
        }
    }
    

    LockSupport

    锁支持:用于实现锁的支持方法,可以阻塞线程

    public class TestLockSupport {
    public static void main(String[] args) {
    Thread t = new Thread(() -> {
    for (int i = 0; i < 10; i++) {
    System.out.println(i);
    if (i == 5) {
    LockSupport.park();
    }
    try {
    TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    });
    t.start();
    LockSupport.unpark(t);
    /*try {
    TimeUnit.SECONDS.sleep(8);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("after 8 senconds!");
    LockSupport.unpark(t);*/
    }
    }
    
  • 相关阅读:
    获得目标服务器中所有数据库名、表名、列名
    SQL Server 2008 安装SQLDMO.dll
    三层交换原理
    NAT地址转换原理全攻略
    C#中显/隐式实现接口及其访问方法
    As,is含义?using 语句
    c#泛型约束
    C#几个经常犯错误汇总
    C#--深入分析委托与事件
    markdown基础
  • 原文地址:https://www.cnblogs.com/gongcheng-/p/14531014.html
Copyright © 2020-2023  润新知