一、重入锁
重入锁是synchronized,Object.wait(),Object.notify()和替代品;
重入锁的类是:java.util.concurrent.locks.ReentrantLock;
代码如:
lock=new ReentrantLock();
lock.lock(); //加锁
.....
lock.unlock();//解锁
二、中断响应
lock=new ReentrantLock();
lock2=new ReentrantLock();
lock.lockInterruptibly(); //请求锁
.....
lock2.interrupt(); //发出中断信号
三、锁申请等待限时
lock.tryLock();返回值是boolean类型;接收两个参数,一个表示等待时长,第二个表示记时单位;没参数时,是不等待;如果获取了锁,返回true;
与lock.tryLock()对应的方法解锁lock.unLock();
四、公平锁
默认情况下,锁是非公平的;synchronized实现的锁就是非公平的;
lock=new ReentrantLock(true);这就是公平锁,公平锁耗资源;
五、ReenreantLock的几个重要方法:
lock();获得锁,如果锁已经被占用,则等待;
lockInterruptibly();获得锁,但优先响应中断;
tryLock();尝试获得锁,如果成功获取,返回true;否则返回false;
tryLock(long time,TimeUnit unit);同上,只是在给定的时间内尝试去获得锁;
unlock();释放锁;
六、重入锁的好搭档,Condition条件
await();使当前线程等待,同时释放当前的锁;当其它线程singal()之后,此线程会重新获得锁并继续执行。
awaitUninterruptibly();与await()方法基本想同,但不会在等待过程中响应中断;
singal()用于唤醒一个在等待中的线程;
七、信号量(semaphore)
信号量可以指定多个线程,同时访问某一个资源;synchronized与重入锁ReentrantLock,一次都只允许一个线程访问一个资源;
其构造方法:
public Semaphore(int permits);参数表示可以申请多少个许可;
public Semphore(int permits,boolean fair);第二个参数表示是否公平;
acquire()尝试获得一个准入的许可,若无法获得,则线程会等待,直到有线程释放一个许可或者当前线程被中断;
acquireUninterruptibly()方法与acquire()方法类似,但不响应中断;
tryAcquire()尝试获得一个许可,如果成功返回true,失败则返回false;
release()用于在线程访问资源结束后,释放一个许可;
八、读写分离锁(ReadWriteLock)
ReentrantReadWriteLock
九、多线程控制工具类
倒计时器 CountDownLatch;
循环栅栏 CyclicBarrier;
十、线程阻塞工具类
LockSupport
十一、线程池
避免系统频繁地创建和销毁线程,可以让创建的线程进行复用。
JDK提供了一套Executor框架,其本质就是一个线程池。
工厂方法:
newFixedThreadPool();返回一个固定线程数量的线程池。
newSingleThreadExecutor();返回只有一个线程的线程池;
newCachedThreadPool();
newSingleThreadScheduledExecutor();在给定的时间执行某任务。如在某个固定的延时之后执行,或者周期性执行某个任务;
十二、分而治之。Fork/Join框架
ForkJoinPool线程池
十三、JDK的并发容器
程序就是算法加数据结构;这些并发容器都是线程安全的。JDK提供的这些容器大部分在:java.util.concurrent包下。
并发集合:适合于多线程场合。
ConcurrentHashMap,一个线程安全的HashMap;
CopyOnWriteArrayList,用在读多写少的场合,是个线程安全的list,其性能好于Vector;
ConcurrentLinkedQueue,是个线程安全的LinkedList;
BlockingQueue,是个接口,JDK内部通过链表(LinkedBlockingQueue)、数组(ArrayBlockingQueue)等方式实现了这个接口,表示阻塞队列,适用于数据共享的通道;
另外,Collections工具类可以将任意集合包装成线程安全的集合;如:
Map p=Collections.synchronizedMap(new HashMap());
ConcurrentSkipListMap的数据是有序的;
网友评论