JUC并发编程之Lock锁

Lock为接口,其实现类为ReetrantLock(可重入锁),其常用方法:

  • void lock();不死不休
  • boolean tryLock();浅尝辄止
  • boolean tryLock(long var1, TimeUnit var3) throws InterruptedException;
  • void unlock();
  • Condition newCondition();

Condition为接口,其常用方法:

  • void await() throws InterruptedException;
  • void signal();

获得锁代码示例:
可重入锁的tryLock方法和lock方法

public class GetLock_Demo {
    static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        lock.lock();//主线程拿到锁

        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {
//                boolean rs = false;
//                try {
//                    //boolean rs = lock.tryLock();
//                    rs = lock.tryLock(1, TimeUnit.SECONDS);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println("是否获取到锁:" + rs);
                System.out.println("尝试获取锁");
                lock.lock();
                System.out.println("获得锁了");
            }
        });
        th.start();

        Thread.sleep(2000L);//睡眠2秒
        th.interrupt();//中断线程运行
        System.out.println("th线程中断了");

        Thread.sleep(5000L);
        lock.unlock();

    }
}

执行结果:

尝试获取锁
th线程中断了
获得锁了

Condition的代码示例:
可重入锁的condition用法

public class Condition_Demo {
    private static Lock lock = new ReentrantLock();
    private static Condition condition = lock.newCondition();

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    System.out.println("当前线程:" + Thread.currentThread().getName() + "获得锁");
                    condition.await();
                    System.out.println("当前线程:" + Thread.currentThread().getName() + "开始执行");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        });

        thread.start();
        Thread.sleep(2000L);
        System.out.println("休眠2秒,来控制线程");
        lock.lock();
        condition.signal();
        lock.unlock();
    }
}

执行结果:

当前线程:Thread-0获得锁
休眠2秒,来控制线程
当前线程:Thread-0开始执行

自定义阻塞队列之ReentrantLock和Condition
通过ReentrantLock和Condition的锁机制自定义阻塞队列

public class BlockingQueue_Demo {
    public static void main(String[] args) throws InterruptedException {
        KaneBlockingQueue kaneBlockingQueue = new KaneBlockingQueue(5);
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    kaneBlockingQueue.put("x" + i);
                }
            }
        }).start();

        Thread.sleep(1000L);
        System.out.println("开始取元素");
        for (int i = 0; i < 10; i++) {
            kaneBlockingQueue.take();
            Thread.sleep(1000L);
        }
    }
}

class KaneBlockingQueue{
    //容器
    List<Object> list = new ArrayList<>();
    private Lock lock = new ReentrantLock();
    private Condition putCondition = lock.newCondition();
    private Condition takeCondition = lock.newCondition();
    private int length;

    public KaneBlockingQueue(int length) {
        this.length = length;
    }

    public void put(Object obj) {
        lock.lock();
        try {
            while (true) {
                if (list.size() < length) {
                    list.add(obj);
                    System.out.println("队列中放入元素:" + obj);
                    takeCondition.signal();
                    return;
                } else {//满了,放不进了
                    putCondition.await();//挂起
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    public Object take() {
        lock.lock();
        try {
            if (list.size() > 0) {
                Object obj = list.remove(0);
                System.out.println("队列中获取的元素:" + obj);
                putCondition.signal();
                return obj;
            } else {
                takeCondition.await();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            return null;
        }
    }
}

执行结果:

队列中放入元素:x0
队列中放入元素:x1
队列中放入元素:x2
队列中放入元素:x3
队列中放入元素:x4
开始取元素
队列中获取的元素:x0
队列中放入元素:x5
队列中获取的元素:x1
队列中放入元素:x6
...

ReentrantLock锁的特性代码示例:
可重入锁ReentrantLock的特性

public class Reetrant_Demo {
    static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        lock.lock();
        System.out.println(Thread.currentThread().getName() + "获得第1次锁");

        lock.lock();//可以重入锁多次
        System.out.println(Thread.currentThread().getName() + "获得第2次锁");

        lock.unlock();//释放不掉
        Thread.sleep(1000L);
        lock.unlock();
        //lock.unlock();//释放多于重入报错

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "开始去获得锁");
                lock.lock();
                System.out.println("获得锁成功");
                lock.unlock();
            }
        }).start();
    }
}

执行结果:

main获得第1次锁
main获得第2次锁
Thread-0开始去获得锁
获得锁成功
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值