标签:异常 except dsc 生产者 实现 obj syn map 也有
synchronized的功能扩展:
重入锁;ReentrantLock;
其实也就是lock对于synchronized的替代了,要注意的一个点就是你可以锁多个,但是你锁了几个,最后就要解锁几个这个问题;
使用lock.lock()加锁,使用lock.unlock()解锁;
提供中断处理;
使用中断锁,线程可以被中断,也就是说,当一个线程正在等待锁的时候,他依然可以收到一个通知,被告知无须等待,可以停止工作了,使用的是lock.lockInterruptibly();方法;
锁申请等待限时;
给锁给定一个时间,如果超过了这个时间的话,就让线程自动放弃;使用的是lock.trylock(时间段,时间单位);另外还有一个就是lock.trylock();如果是带参数的,就是最多等待这么多时间,超过了时间就返回false,成功获得了锁,就返回true;如果是不带参数直接运行,就是比较直接的,如果锁未被占用,则申请锁成功,返回true,否则就是失败了,直接返回false;
公平锁;
公平锁的一个特点就是:它不会产生饥饿现象;所有的锁都是先到先等,不得插队;但是维持公平需要一个有序队列,实现成本较高,性能相对也非常低下,默认情况下,锁是非公平的;
以下是我们整理的几个重要方法:
1,lock():获得锁,如果锁已经被占用,则等待;
2,lockInterruptibly():获得锁,但优先响应中断;
3,tryLock():尝试获得锁,如果成功,返回true,失败返回false,该方法不等待,立即返回;
4,tryLock(Long time,TimeUnit unit):在给定的时间内尝试获得锁;
5,unlock():释放锁;
重入锁的好搭档:Condition条件;
使用new Condition可以生成与当前重入锁绑定的Condition实例;使得我们可以让线程在合适的时间等待,或者在某一特定的时刻得到通知,继续执行;
1,await();让当前线程等待,同时释放当前锁,作用上和wait()相似;
2,awaitUninterruptibly();与await()方法基本相同,不会在等待过程中响应中断;
3,singal();用于唤醒一个在等待中的线程,相对的singalAll()方法会唤醒所有在等待中的线程,和notify()类似;
允许多个线程同时访问:信号量;
只允许一个线程访问一个资源,而信号量则可以指定多个线程;
public Semaphore(int permits)
public Semaphore(int permits,boolean fair);第二个参数可以指定是否公平锁;
这所谓的信号量,其实就是一个执行器啦,只是换了名字看不出来了而已。。。参数可以指定有多少个线程;
ReadWriteLock读写锁;
关于读写的问题,我们要明确的一点就是,我们可以对一个文件多次重复读取,但是当读与写发生冲突的时候,我们要做的就是保证他们的互斥了;
读读不互斥;
读写互斥;
写写互斥;
如果读的操作远远大于写的操作的话,读写锁就会发挥最大的功效;
Lock readLock = readWriteLock.readLock();
Lock writeLock = readWriteLock.writeLock();
读线程完全并行,而写会阻塞读;
倒计时器:CountDownLatch;
此工具通常用来控制线程等待,让某一个线程等待知道倒计时结束,再开始执行;
只有当你一开始设定的所有线程都跑完了,你这个倒计时器才算真正结束了;
CountDownLatch end = new CountDownLatch(10);
end.countDown();
当调用CountDownLatch.countDown()方法的时候,也就是通知CountDownLatch,一个线程已经完成了任务,倒计时器可以减1了;
循环珊栏;CyclicBarrier;
另外一种多线程并发控制实用工具;
其实本质上跟倒计时器是差不多的功能类似,唯一的区别就在于可以反复使用,而且可以设置,当计数结束之后,系统下一步要执行的动作;
public CyclicBarrier(int parties,Runnable barrierAction);
其中barrierAction是执行的动作;
线程阻塞工具类:LockSupport;
可以在线程内任意位置让线程阻塞;和Thread.suspend()相比,弥补了由于resume()在前发生,导致线程无法继续执行的情况;
与object.wait()相比,不需要先获得某个对象的锁,也不会抛出interruptedException异常;
LockSupport.park();
LockSupport.unpark(t1);
除了有定时阻塞的功能外,LockSupport.park()还能支持中断影响;但是LockSuppor.park()不会抛出InterruptedException异常,他只是默默的返回;
也就是说:LockSupport.park()进行阻塞之后,如果中断这个线程,不会抛出异常,而是默默的返回;
线程复用:线程池;
我们在这里用到了池的概念来保存管理我们的线程;
当我们要使用线程的时候,不是创建,而是从池子中去取,当我们要关闭线程的时候,是将这个线程返回给池子,方便其他人使用;
JDK对线程池的支持;
newFixedThreadPool(int nThreads);
newSingleThreadExecutor();
newCachedThreadTool();
newSingleThreadScheduledExector();
newScheduledThreadPool(int corePoolSize);
newFixedThreadPool():该方法返回一个固定线程数量的线程池;线程池的数量保持不变,若线程池已满,新的任务会被暂存在一个任务队列中;
newSingleThreadExecutor();该线程池只有一个线程在里面,多余任务会被保存到一个任务队列中;
newCachedThreadPool();返回一个根据实际情况调整线程数量的线程池,也就是说,这个线程池中的线程是可以可调整的。当所有的线程都在工作而此时又有新的任务提交,则会扩展线程的数量;
newSingleThreadScheduledExecutor();返回一个ScheduledExecutorService对象,在ExecutorService接口上扩展了在给定时间执行某任务的功能,
newScheduledThreadPool()方法,可以指定线程数量和时间的线程池;
核心线程池的内部实现;
都是在原有的ThreadPoolExecutor()的基础上进行的参数设置和修改;
而其实,这个ThreadPoolExecutor()内部的参数也有很多的;
int corePoolSize;线程池中线程的数量;
int maximumPoolSize;指定了线程池的最大线程数量;
long keepAliveTime;当线程池数量超过了corePoolSize时吗,多与的空闲线程的存活时间;
TimeUnit unit;keepAliveTime的时间单位;
BlockingQueue<Runnable> workQueue:任务队列,被提交但尚未被执行的任务;
ThreadFactory threadFactory;线程工厂,用于创建线程,一般用默认的;
handler;拒绝策略,当任务太多来不及处理,如何拒绝任务;
现在我们上面的几个线程池是如何通过ThreadPoolExecutor()以及内部的参数来设定的呢,我们现在就来说一下;
其中newFixedThreadPool(nThreads,nThreads,0L,new LinkedBlockingQueue<Runnable>);
newSingleThreadExecutor(1,1,0L,new LinkedBlockingQueue<Runnable>);
newCachedThreadPool(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
其中,我们可以看出,当newCachedThreadPool时,我们是指定线程池数量为0,但是最大线程数为无限,而且采用的任务队列跟上面的队列不一样,下面将重点说明这两种任务队列的不同之处;
SynchronousQueue:这是直接提交的队列,每一个线程都会直接提交,不会真实地保存,而是直接将新任务交给线程执行器;
ArrayBlockingQueue:这是有界的任务队列,需要带一个参数,表示该队列的最大容量;
LinkedBlockingQueue:这是无界的任务队列,多余的任务会先放到这里;
PriorityBlockingQueue:这是优先任务队列,根据任务自身的优先级顺序先后执行;
不要重复发明轮子:JDK的并发容器;
ConcurrentHashMap:高效的并发HashMap;
CopyOnWriteArrayList:在读多写少的场合,这个List的性能非常好,远远好于Vector(另外。。Vector已经过时了,不用了);
ConcurrentLinkedQueue:高效的并发队列,使用链表实现,可以看做一个线程安全的LinkedList;
BlockingQueue:表示阻塞队列,详情可以查看一下生产者——消费者模式;
ConcurrentSkipListMap:跳表的实现;这是一个Map,使用跳表的数据结构进行快速查找;
以上并发容器的内部数据结构实现,我们在下一章会提到;敬请期待!
JDK并发相关并发包
标签:异常 except dsc 生产者 实现 obj syn map 也有
原文地址:https://www.cnblogs.com/zxx123/p/9736046.html