java concurrent 并发包学习记录

未完待续

 

参考:

https://blog.csdn.net/wbwjx/article/details/57856045

https://blog.csdn.net/defonds/article/details/44021605#t19

http://www.blogjava.net/xylz/archive/2010/07/08/325587.html

请先参考上面的链接,本文只是作为记录我学习博客的过程

java.util.concurrent 包是专为 Java并发编程而设计的包。包下的所有类可以分为如下几大类:

locks部分:显式锁(互斥锁和速写锁)相关;
atomic部分:原子变量类相关,是构建非阻塞算法的基础;
executor部分:线程池相关;
collections部分:并发容器相关;
tools部分:同步工具相关,如信号量、闭锁、栅栏等功能;

 

脑图地址: http://www.xmind.net/m/tJy5

Lock部分

类似于synchronized 的线程同步机制

自旋锁:如果获取锁未获取到,会一直循环查看是否锁被释放

互斥锁:如果获取锁未获取到,会进入睡眠状态等待

共享锁:只是一个标志,所有线程都等待这个标志是否满足,一旦满足,所有线程都被激活

ReentrantLock 可重入锁

可中断响应、锁申请等待限时、公平锁等机制,以及结合Condition使用

1.可中断响应:

当两个线程1,2分别持有锁A和锁B并等待锁B和锁A,这样就发生了死锁,但是ReentrantLock可中断线程,中断线程2后,线程2释放锁B并不在等待锁A,此时线程1获取锁执行任务,但是线程2也并没有完成工作

public class LockTest1 {


    static class KillDeadlock implements Runnable{

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

        public KillDeadlock(int lock){

            this.lock = lock;
        }


        @Override
        public void run() {
            try {
                if (lock ==1){
                    lock1.lockInterruptibly();
                    try {
                        Thread.sleep(5000);

                    }catch (InterruptedException e){
                    }
                    lock2.lockInterruptibly();
                }else {
                    lock2.lockInterruptibly();
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                    }
                    lock1.lockInterruptibly();
                }
            } 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 Exception{
        KillDeadlock k1 = new KillDeadlock(1);
        KillDeadlock k2 = new KillDeadlock(2);
        Thread t1 = new Thread(k1);
        Thread t2 = new Thread(k2);
        t1.start();t2.start();
        Thread.sleep(10000);
        t1.interrupt();

    }

}
中断响应

2.锁申请限时等待

可以使用tryLock()或tryLock(long timeout, TimeUtil unit) 方法进行一次限时的锁等待。

前者如果获取不到锁,会立即返回false,后者等待一段时间后返回false

3.公平锁

公平锁会按照时间先后顺序,先等待的先得到锁,而且不会产生饥饿锁,只要排队等待,最终能得到获取锁的机会

4.Condition 配合使用

如果获取锁后,发现部分参数不满足后面执行的条件,可以调用condition的await方法,继续等待,等待其他线程修改参数后,继续执行

public class ReentrantLockWithConditon implements Runnable{
    public static ReentrantLock lock = new ReentrantLock(true);
    public static Condition condition = lock.newCondition();

    @Override
    public void run() {
        lock.newCondition();
        try {
            lock.lock();
            System.err.println(Thread.currentThread().getName() + "-线程开始等待...");
            condition.await();
            System.err.println(Thread.currentThread().getName() + "-线程继续进行了");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReentrantLockWithConditon test = new ReentrantLockWithConditon();
        Thread t = new Thread(test, "线程ABC");
        t.start();
        Thread.sleep(1000);
        System.err.println("过了1秒后...");
        lock.lock();
        condition.signal(); // 调用该方法前需要获取到创建该对象的锁否则会产生
                            // java.lang.IllegalMonitorStateException异常
        lock.unlock();
    }
}
--------------------- 
作者:Somhu 
来源:CSDN 
原文:https://blog.csdn.net/Somhu/article/details/78874634 
版权声明:本文为博主原创文章,转载请附上博文链接!
Condition

ReadWriteLock 读写锁

允许多个线程在同一时间对特定资源进行读取,但同一时间内只能有一个线程对其写入

实现类:ReentrantReadWriteLock

  • 如果没有任何写操作锁定,那么可以有多个读操作锁定该锁
  • 如果没有任何读操作或者写操作,只能有一个写线程对该锁进行锁定。

CountDownLatch 闭锁

基于共享锁实现。允许一个或者多个线程等待某个事件的发生。CountDownLatch有一个正数计数器,countDown方法对计数器做减操作,await方法等待计数器达到0。所有await的线程都会阻塞直到计数器为0或者等待线程中断或者超时。

CyclicBarrier 循环锁

可循环调用,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。所谓屏障点就是一组任务执行完毕的时刻。

 

Atomic 部分

原子性包装

将数据进行原子性封装,变量级别的同步控制,同一时间只能有一个线程操作

Collections 部分

Queue  队列:

BlockingQueue extends Queue   阻塞队列

使用场景: 一个线程生产对象,另外一个线程消费对象:

有限的队列,队列满时,put会阻塞,队列空时,take会阻塞

SpecialValue : 如果操作无法执行,将返回一个特定的值,通常是true/false

注意:无法插入null

数据结构导致,除了获取开头和结尾之外的其他位置效率都不高

 

ArrayBlockingQueue 有界的阻塞队列

ConcurrentMap 线程安全Map

 

posted @ 2018-11-19 14:56  我是小明呀嘿  阅读(1183)  评论(0编辑  收藏  举报