• 各种同步控制工具的使用


    Semaphore

    概述

    共享锁,运行多个线程同时临界区

    主要接口

    public void acquire()
    public void acquireUninterruptibly()
    public boolean tryAcquire()
    public boolean tryAcquire(long timeout, TimeUnit unit)
    public void release()

    使用

    public class SemaphoreDemo {
        private static final int THREAD_COUNT = 3;
        private static ExecutorService threadPool = Executors
            .newFixedThreadPool(THREAD_COUNT);
    
        private static Semaphore s = new Semaphore(1);
        public static void main(String[] args) {
            for(int i=0;i<3;i++)
            {
                threadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            System.out.println(Thread.currentThread().getName()+"start data");
                            Thread.sleep(2000);
                            s.acquire();
                            Thread.sleep(1000);
                            System.out.println(Thread.currentThread().getName()+"save data");
                            s.release();
                            System.out.println(Thread.currentThread().getName()+"release data");
                            Thread.sleep(2000);
                            System.out.println(Thread.currentThread().getName()+"end data");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            threadPool.shutdown();
        }
    }
    

     最后得出一个比较有意思的结论:Semaphore 像是一个共享的屋子,这个屋子里面只能有一定的人数,这个人数是所有人可以看到的,甚至与release()这个方法,可以被别的线程进行调用,

    一般使用acquire()  与release() 这个之间的代码只能有固定数量的线程存在,当然这种是当前线程进行获取和释放

    ReadWriteLock

    概述

    ReadWriteLockJDK5中提供的写分离

    -不互斥:读读不阻塞。
    -写互斥:阻塞写,写也会阻塞
    -写互斥:写写阻塞。

    主要使用

    private static ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();
    private static Lock readLock = readWriteLock.readLock();
    private static Lock writeLock = readWriteLock.writeLock();

    这个类如果没有写锁的情况下,读是无阻塞的,在一定程度上提高了程序的执行效率。

      public void run() {  
                     //isRead自定义变量(判断这个线程是读还是写)
                     if (isRead) {  
                             //获取读锁  
                             myLock.readLock().lock();  
                             System.out.println("读");
                             //释放读锁  
                             myLock.readLock().unlock();  
                     } else {  
                             //获取写锁  
                             myLock.writeLock().lock();  
                             //执行现金业务  
                                     System.out.println("写");
                             //释放写锁  
                             myLock.writeLock().unlock();  
                     }  
             }                                          
    

     CountDownLatch

    概述:

    static final CountDownLatch end = new CountDownLatch(10);
    end.countDown();   //这个方法是子线程作完作业之后,调用的
    end.await(); //主线等待指定数量的子线程完成作业,当所有子线程完成之后,主线程自动激活执行

    public class CountDownLatchDemo {
        private static CountDownLatch countDownLatch=new CountDownLatch(10);
        public static void main(String[] args) {
            for(int i=0;i<10;i++)
            {
               new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println(Thread.currentThread().getName()+"work");
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        countDownLatch.countDown();
    
                    }
                }).start();
            }
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch.await();
                        System.out.println(Thread.currentThread().getName()+"主线程start");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },"main1").start();
        }
    }
    

     CyclicBarrier

    概述

    public class CyclicBarrierDemo {
        public static class Soldier implements Runnable{
            private  String name;
            private final CyclicBarrier cyclicBarrier;
    
            public Soldier(String name,CyclicBarrier c) {
                this.name = name;
                this.cyclicBarrier=c;
            }
    
            @Override
            public void run() {
                  try{
                      //等待所有士兵到齐
                      System.out.println(name +"报道");
                      cyclicBarrier.await();
                        dowork();
                      //等待所有士兵完成工作
                      cyclicBarrier.await();
    
                  }
                  catch (Exception e)
                  {
                      e.printStackTrace();
                  }
            }
            public void dowork()
            {
                    System.out.println(name +"完成任务");
            }
        }
    
        public static class BarrierRun implements Runnable{
            boolean flag;
            int  number;
            public BarrierRun(boolean flag, int number) {
                this.flag = flag;
                this.number = number;
            }
    
            @Override
            public void run() {
                if(!flag)
                {
                    System.out.println("士兵集合完毕");
                    flag=true;
                    System.out.println("开始执行任务");
                }
                else{
                    System.out.println("任务完成");
    
                }
            }
        }
        public static void main(String[] args) {
            final  int N =10;
    
            CyclicBarrier barrier =new CyclicBarrier(N,new BarrierRun(false,N));
            System.out.println("集合队伍");
            for(int i=0;i<N;i++)
            {
                new Thread(new Soldier("士兵"+i,barrier)).start();
            }
        }
    }
    

     每次CyclicBarrier 调用await()方法之后,都会等待所有的子线程,之后执行CyclicBarrier 的Runnable的方法

    LockSupport

    概述

    unpark函数可以先于park调用。比如线程B调用unpark函数,给线程A发了一个“许可”,那么当线程A调用park时,它发现已经有“许可”了,那么它会马上再继续运行。

    park和unpark的灵活之处

    上面已经提到,unpark函数可以先于park调用,这个正是它们的灵活之处。

    一个线程它有可能在别的线程unPark之前,或者之后,或者同时调用了park,那么因为park的特性,它可以不用担心自己的park的时序问题

  • 相关阅读:
    [MySQL] 日志文件概述
    ASP.NET session expired simple solution
    Sailfish应用开发入门(一)ApplicationWindow与Cover
    linux下QT4的使用
    js控制图片定时切换不限制数量
    C++ 从零单排(3)
    wordcraft(陈高远)
    苦逼翻滚之实习找工记事产品岗(3.184.23长文慎入)
    【Oracle导入导出】expdp
    【leetcode】Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/lizhiyan-world/p/6911082.html
Copyright © 2020-2023  润新知