zoukankan      html  css  js  c++  java
  • 20.ReenterLock重入锁

    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 重入锁 ReenterLock 一个线程允许连续获得同一把锁,注意:必须释放相同次数,释放次数多,会异常,少了相当于线程还持有这个锁,其他线程无法进入临界区
     * 需要手动指定何时加锁何时释放锁
     *
        ReenterLock几个重要方法:
        - lock():获得锁,如果锁已经被占用,则等待
        - lockInterruptibly():获得锁,但优先响应中断
        - tryLock():尝试获得锁,成功返回true,失败返回false,该方法不等待,立即返回
        - tryLock(long time,TimeUnit unit):在给定时间内尝试获得锁
        - unlock():释放锁
     */
    public class ReentrantLockDemo implements Runnable{
        public static Integer i = 0;
        public static ReentrantLock lock = new ReentrantLock();
    
        @Override
        public void run() {
            for (int j = 0; j < 10000000; j++) {
                lock.lock();
                try {
                    i++;
                }finally {
                    lock.unlock();
                }
            }
        }
        public static void main(String[] args) throws InterruptedException{
            ReentrantLockDemo r = new ReentrantLockDemo();
            Thread thread1 = new Thread(r);
            Thread thread2 = new Thread(r);
            thread1.start();thread2.start();
            thread1.join();thread2.join();
            System.out.println(i);//20000000
        }
    }
    

    中断处理

    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 避免死锁
     * 重入锁的中断处理能力
     */
    public class IntLock implements Runnable{
        public static ReentrantLock lock1 = new ReentrantLock();
        public static ReentrantLock lock2 = new ReentrantLock();
        int lock;
        public IntLock(int lock) {
            this.lock = lock;
        }
        @Override
        public void run() {
            try {
                if (lock==1){
                    lock1.lockInterruptibly();
                    Thread.sleep(500);
                    lock2.lockInterruptibly();//可以对中断进行响应的锁
                }else {
                    lock2.lockInterruptibly();
                    Thread.sleep(500);
                    lock1.lockInterruptibly();  //22行
                }
            }catch (InterruptedException e){
                e.printStackTrace();
            }finally {
                //检查当前线程是否拥有该锁
                if (lock1.isHeldByCurrentThread()) lock1.unlock();
                if (lock2.isHeldByCurrentThread()) lock2.unlock();
                System.out.println(Thread.currentThread().getId()+":线程退出");
            }
        }
        public static void main(String[] args) throws InterruptedException{
            IntLock i1 = new IntLock(1);
            IntLock i2 = new IntLock(2);
            Thread t1 = new Thread(i1);
            Thread t2 = new Thread(i2);
            t1.start();
            t2.start();
            Thread.sleep(1000);
            t2.interrupt(); //中断t2 ,t2放弃对lock1的申请,同时释放已获得的lock2
            //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.combat.IntLock.run(IntLock.java:22)
            //	at java.lang.Thread.run(Thread.java:748)
            //10:线程退出
            //9:线程退出
        }
    }
    

    限时等待

    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 限时等待锁
     */
    public class TimeLockDemo implements Runnable{
        public static ReentrantLock lock = new ReentrantLock();
        @Override
        public void run() {
            try {
                if (lock.tryLock(5, TimeUnit.SECONDS)){ //等待时间,计时单位
                    Thread.sleep(6000);
                }else {
                    System.out.println("get lock failed");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (lock.isHeldByCurrentThread())lock.unlock();
            }
        }
        public static void main(String[] args){
            TimeLockDemo demo = new TimeLockDemo();
            Thread t1 = new Thread(demo);
            Thread t2 = new Thread(demo);
            t1.start();
            t2.start();
        }
        //get lock failed
        //由于占用锁的线程为6秒,另一个线程无法在5秒的等待时间内获得锁,因此请求锁失败
    }
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * tryLock
     * 限时等待锁 无参数  如果锁被其他线程占用,则当前线程不会进行等待,而是立即返回false,不会引起线程等待
     */
    public class TimeLockDemo2 implements Runnable{
        public static ReentrantLock lock1 = new ReentrantLock();
        public static ReentrantLock lock2 = new ReentrantLock();
        int lock;
        public TimeLockDemo2(int lock) {
            this.lock = lock;
        }
        @Override
        public void run() {
            if (lock == 1){
                while (true){
                    if (lock1.tryLock()){
                        try {
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            if (lock2.tryLock()){
                                try {
                                    System.out.println(Thread.currentThread().getId()+":my job done");
                                    return;
                                } finally {
                                    lock2.unlock();
                                }
                            }
                        } finally {
                            lock1.unlock();
                        }
                    }
                }
            }else {
                while (true){
                    if (lock2.tryLock()){
                        try {
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            if (lock1.tryLock()){
                                try {
                                    System.out.println(Thread.currentThread().getId()+":my job done");
                                    return;
                                } finally {
                                    lock1.unlock();
                                }
                            }
                        } finally {
                            lock2.unlock();
                        }
                    }
                }
            }
        }
        public static void main(String[] args){
            TimeLockDemo2 r1 = new TimeLockDemo2(1);
            TimeLockDemo2 r2 = new TimeLockDemo2(1);
            Thread t1 = new Thread(r1);
            Thread t2 = new Thread(r2);
            t1.start();
            t2.start();
        }
        //9:my job done
        //10:my job done
    }
    

    公平锁

    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 公平锁
     * synchronized产生的锁是非公平锁
     * 重入锁可以设置公平性
     */
    public class FairLock implements Runnable{
        public static ReentrantLock lock = new ReentrantLock(true);
        @Override
        public void run() {
            while (true){
                try {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName()+"获得锁");
                } finally {
                    lock.unlock();
                }
            }
        }
        public static void main(String[] args) throws InterruptedException{
            FairLock lock = new FairLock();
            Thread t1 = new Thread(lock, "thread_t1");
            Thread t2 = new Thread(lock, "thread_t2");
            t1.start();
            t2.start();
        }
        //...
        //thread_t2获得锁
        //thread_t1获得锁
        //thread_t2获得锁
        //thread_t1获得锁
        //thread_t2获得锁
        //...
        //两个线程基本交替获得锁
    
        //而非公平锁,一个线程会倾向于再次获得已持有的锁,这种分配方式是高效的,但无公平性可言
    }
    
  • 相关阅读:
    补题列表
    task list
    UVa 11809
    UVA 272 TEX Quotes 题解
    莱州一中2016高考加油视频
    POJ2367-Genealogical tree-拓扑排序
    POJ1094-Sorting It All Out-拓扑排序
    POJ3660-Permutations-传递闭包FLOYD
    POJ3687- Labeling Balls-优先队列拓扑排序
    POJ1201-Intervals- 差分约束
  • 原文地址:https://www.cnblogs.com/fly-book/p/11388614.html
Copyright © 2011-2022 走看看