concurrent-2-同步控制

重入锁 ReentrantLock

重入锁示例
     lock : 获取锁资源
     unLock : 释放锁资源
//重入锁示例
public class TestReentrantLock {

    public static ReentrantLock lock=new ReentrantLock();  //重入锁

    public static  int count = 0 ;

    public static void main(String[] args) {

        for (int i = 0 ; i < 3 ; i++ ) {
           Thread thread = new Thread(
                    ()->{
                        while (true) {
                            lock.lock();  //获取锁
                            count++ ;
                            if (count > 1000000) {
                                break;
                            }
                            System.out.println(Thread.currentThread().getName() + "  ----"+ count);
                            lock.unlock();  //释放锁
                        }
                    }
            ,"thread--" + i);
           thread.start();
        }
    }
}
//输出
thread--2  ----999996
thread--2  ----999997
thread--2  ----999998
thread--2  ----999999
thread--2  ----1000000
中断响应
     lockInterruptibly : 如果线程中断,停止对锁的等待
     isHeldByCurrentThread : 判断当前线程是否含有该锁
//中断响应示例
public class TestReentrantLock {

    public static ReentrantLock lock1=new ReentrantLock();
    public static ReentrantLock lock2=new ReentrantLock();

    public static int count=0;

    public static void main(String[] args) {
        Thread thread=null;
        for (int i=1; i < 3; i++) {
           thread=new Thread(
                    () -> {
                            try {
                                if (Thread.currentThread().getName().equals("thread--1")) {
                                    lock1.lockInterruptibly();  //获取锁 1
                                    System.out.println(Thread.currentThread().getName() +  " lock1 lock ");
                                    try {
                                        Thread.sleep(5000);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    lock2.lockInterruptibly();//获取锁 2
                                    System.out.println(Thread.currentThread().getName() +  " lock2 lock ");
                                } else {
                                    lock2.lockInterruptibly();  //获取锁 2
                                    System.out.println(Thread.currentThread().getName() +  " lock2 lock ");
                                    try {
                                        Thread.sleep(5000);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    lock1.lockInterruptibly();//获取锁 1
                                    System.out.println(Thread.currentThread().getName() +  " lock1 lock ");
                                }
                                count++;
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            } finally {
                                System.out.println(Thread.currentThread().getName() + "  ----" + count);
                                if (lock1.isHeldByCurrentThread()) {
                                    lock1.unlock(); //释放锁
                                    System.out.println(Thread.currentThread().getName() + " lock1 unlock ");
                                }
                                if (lock2.isHeldByCurrentThread()) {
                                    lock2.unlock(); //释放锁
                                    System.out.println(Thread.currentThread().getName() + " lock2 unlock ");

                                }
                            }

                        }
                    , "thread--" + i);
            thread.start();
        }
        try {
            Thread.sleep(8000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count);
        thread.interrupt();  //中断线程2
        //输出
        thread--2 lock2 lock 
    thread--1 lock1 lock 
    0
    thread--2  ----0
    thread--2 lock2 unlock 
    thread--1 lock2 lock 
    thread--1  ----1
    thread--1 lock1 unlock 
    thread--1 lock2 unlock 
    java.lang.InterruptedException
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
        at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
        at com.mybatis.datasources.common.concurrent.TestReentrantLock.lambda$main$0(TestReentrantLock.java:40)
        at java.lang.Thread.run(Thread.java:745)
限时等待
    // 限时等待 在指定时间未获得锁资源后不再等待。
    lock.tryLock(5, TimeUnit.SECONDS) // 5秒后不再等待
 public static ReentrantLock lock=new ReentrantLock();

    // 限时等待 在指定时间未获得锁资源后不再等待。
    public static void main(String[] args) {
        for (int i=1; i < 3; i++) {
            new Thread(
                    () -> {
                        try {
                            if (lock.tryLock(5, TimeUnit.SECONDS)) {
                                System.out.println(Thread.currentThread().getName() + "  get lock success ");
                                Thread.sleep(3);
                                lock.unlock();
                            } else {
                                System.out.println(Thread.currentThread().getName() + "  get lock fail ");
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    , "thread --" + i).start();
        }
    }
    //输出
    thread --2  get lock success 
    thread --1  get lock success 
公平锁
    //公平锁,获取cpu执行权的几率相同
  public static ReentrantLock fairLock=new ReentrantLock(true);

    public static void main(String[] args) {
        for(int i = 1 ; i< 3 ; i++) {
            Thread thread=new Thread(
                    () -> {
                        while (true) {
                            fairLock.lock();
                            System.out.println(Thread.currentThread().getName() + " is getLocked");
                            fairLock.unlock();
                        }
                    }
                    , "thread -- " + i);
            thread.start();
        }
    }
    //输出
    thread -- 2 is getLocked
    thread -- 1 is getLocked
    thread -- 2 is getLocked
    thread -- 1 is getLocked
    thread -- 2 is getLocked
    thread -- 1 is getLocked

条件condition

        ReentrantLock配合使用
    //await :挂起线程等待,释放锁资源
    //signal : 唤醒线程
    public static ReentrantLock lock=new ReentrantLock();
    public static Condition condition = lock.newCondition();

    public static void main(String[] args) {
        Thread thread=new Thread(
                ()->{
                    lock.lock();
                    try {
                        System.out.println(Thread.currentThread().getName() +" is wait ");
                        condition.await();  //释放锁资源
                    } catch (InterruptedException e) {
                    }
                    System.out.println(Thread.currentThread().getName() +" is notify and end ");
                    lock.unlock();
                }
        ," thread -- 1");
        thread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        lock.lock();
        condition.signal();  //叫醒等待线程。
        lock.unlock();
    }
    //输出
     thread -- 1 is wait 
     thread -- 1 is notify and end 

Semaphore信号量

     //信号量
    //可以控制同时执行的线程数量
    //semaphore.acquire();   计数
    //semaphore.release();  释放线程
    public static Semaphore semaphore=new Semaphore(5);

    public static void main(String[] args) {

        ExecutorService executorService=Executors.newFixedThreadPool(20);

        for(int i = 0 ; i <20 ; i ++) {
            executorService.submit(
                    ()->{
                        try {
                            semaphore.acquire();
                            Thread.sleep(2000);
                            System.out.println(Thread.currentThread().getId() +" is end");
                            semaphore.release();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
            );
        }
        executorService.shutdown();
    }
}
//输出   每次都是五个线程执行
13 is end
11 is end
14 is end
15 is end
12 is end
20 is end
16 is end
17 is end
18 is end
19 is end
22 is end
25 is end
21 is end
24 is end
23 is end
29 is end
26 is end
30 is end
28 is end
27 is end

ReentantReadWriteLock 读写锁

        //读写锁
        //读写:会互相阻塞
        //写写:会互相阻塞
        //读读:不会阻塞
 public static Lock lock = new ReentrantLock();
    public static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

      public static Lock readLock = reentrantReadWriteLock.readLock();  //读锁

      public static Lock writeLock = reentrantReadWriteLock.writeLock(); //写锁

      public static int count ;

    public static int read(Lock lock) {
        lock.lock();
        try {
            Thread.sleep(1000);
            System.out.println(System.currentTimeMillis() + " read " + count);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        return  count ;
    }

    public static void write(Lock lock,int count) {
        lock.lock();
        try {
            Thread.sleep(500);
            System.out.println(System.currentTimeMillis() + "  write " + count);
            TestReadWriteLock.count = count;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {

        for(int i = 0 ; i < 20 ;i ++) {
            new Thread(
                    ()-> read(lock)   //20个线程进行读的操作
                    //()-> read(readLock)
            ).start();
        }
        for (int i = 0; i< 2; i ++) {
            new Thread(          //2个线程进行写的操作
                    ()-> write(lock,new Random().nextInt(10))
                    //()-> write(writeLock,new Random().nextInt(10))
            ).start();
        }
    }
    //输出1   重入锁
    //        1495871944846 read 0
    //        1495871945847 read 0
    //        1495871946847 read 0
    //        1495871947847 read 0
    //        1495871948848 read 0
    //        1495871949848 read 0
    //        1495871950848 read 0
    //        1495871951848 read 0
    //        1495871952848 read 0
    //        1495871953848 read 0
    //        1495871954848 read 0
    //        1495871955848 read 0
    //        1495871956848 read 0
    //        1495871957848 read 0
    //        1495871958848 read 0
    //        1495871959848 read 0
    //        1495871960848 read 0
    //        1495871961848 read 0
    //        1495871962848 read 0
    //        1495871963849 read 0
    //        1495871964349  write 0
    //        1495871964849  write 9

    //输出2   读写锁
    //        1495871787331 read 0
    //        1495871787332 read 0
    //        1495871787333 read 0
    //        1495871787336 read 0
    //        1495871787342 read 0
    //        1495871787345 read 0
    //        1495871787352 read 0
    //        1495871787352 read 0
    //        1495871787352 read 0
    //        1495871787352 read 0
    //        1495871787352 read 0
    //        1495871787854  write 6
    //        1495871788855 read 6
    //        1495871788855 read 6
    //        1495871788855 read 6
    //        1495871788855 read 6
    //        1495871788855 read 6
    //        1495871788855 read 6
    //        1495871789356  write 3
    //        1495871790356 read 3
    //        1495871790356 read 3
    //        1495871790356 read 3

CountDownLatch 倒计时器

    //倒计时器
    //控制多线程等待,指定数量线程完成后执行主线程
    countDownLatch.await();   //等待计数
    public static CountDownLatch countDownLatch=new CountDownLatch(10);

    public static void main(String[] args) {
        ExecutorService executorService=Executors.newFixedThreadPool(10);
        for(int i = 0 ; i < 10 ; i++ ) {
            executorService.submit(
                    ()->{
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                        }
                        System.out.println(" thread is end ");
                        countDownLatch.countDown();
                    }
            );
        }
        try {
            countDownLatch.await();  //等待计数器完成后执行
        } catch (InterruptedException e) {
        }
        System.out.println(" countDownLatch is end ");
        executorService.shutdown();
    }
    //输出
    //thread is end
    //thread is end
    //thread is end
    //thread is end
    //thread is end
    //thread is end
    //thread is end
    //thread is end
    //thread is end
    //thread is end
    //countDownLatch is end

循环栅栏CyclicBarrier

      //循环栅栏
    //每达到指定的N个线程后执行栅栏中的任务
    cyclicBarrier.await();   //计数等待
    public static boolean flag = false ;

    public static void main(String[] args) {

        CyclicBarrier cyclicBarrier =   new CyclicBarrier(10,
                ()->{
                    if (flag) {
                        System.out.println( "thread is done");
                    }else{
                        System.out.println(" thread is coming");
                        flag = true;
                    }
                }
        );
        for(int i = 0 ; i < 10 ; i ++) {
            new Thread(
                    ()->{
                        try {
                            cyclicBarrier.await();   //计数等待
                            //do work
                            Thread.sleep(1000);
                            System.out.println(Thread.currentThread().getName() + " is running");
                            //cyclicBarrier.await();  //计数等待
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (BrokenBarrierException e) {
                            e.printStackTrace();
                        }
                    }
            ," thread -- " + i).start();
        }
        //输出1  :无任务注释
        //thread is coming
        //thread -- 0 is running
        //thread -- 9 is running
        //thread -- 1 is running
        //thread -- 2 is running
        //thread -- 8 is running
        //thread -- 4 is running
        //thread -- 5 is running
        //thread -- 3 is running
        //thread -- 7 is running
        //thread -- 6 is running
        //thread is done
        //输出2  注释第一个   cyclicBarrier.await();
        //thread -- 1 is running
        //thread -- 3 is running
        //thread -- 7 is running
        //thread -- 5 is running
        //thread -- 9 is running
        //thread -- 0 is running
        //thread -- 8 is running
        //thread -- 4 is running
        //thread -- 2 is running
        //thread -- 6 is running
        //thread is coming
        //输出3   注释第二个   cyclicBarrier.await();
        //thread is coming
        //thread -- 3 is running
        //thread -- 7 is running
        //thread -- 5 is running
        //thread -- 1 is running
        //thread -- 9 is running
        //thread -- 2 is running
        //thread -- 6 is running
        //thread -- 8 is running
        //thread -- 0 is running
        //thread -- 4 is running
    }

线程阻塞

    //  LockSupport
    //  LockSupport.park();  //阻塞线程  不会释放锁资源,会立刻中断响应
    //  LockSupport.unpark(thread1);  
    public static  Object object = new Object();

    public static void main(String[] args) {
        Thread thread1 = new Thread(
                ()->{
                    synchronized (object) {
                        System.out.println(Thread.currentThread().getName() + " is running");
                        LockSupport.park();  //阻塞线程  不会释放锁资源
                        System.out.println(Thread.currentThread().getName() + " is end");
                    }
                }
        ,"thread -- 1");
        Thread thread2 = new Thread(
                ()->{
                    synchronized (object) {
                        System.out.println(Thread.currentThread().getName() + " is running");
                        LockSupport.park();  //阻塞线程  不会释放锁资源
                        System.out.println(Thread.currentThread().getName() + " is end");
                    }
                }
        ," thread -- 2");
        thread1.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread2.start();
        LockSupport.unpark(thread1);
        LockSupport.unpark(thread2);
    }
    //输出
    //thread -- 1 is running
    //thread -- 1 is end
    //thread -- 2 is running
    //thread -- 2 is end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值