java的concurrent包中的锁lock;工具类:CyclicBarrier、semaphore、CountDownLatch;集合:blockingquue、concurrentMap;原子量:aotmic。先从下面的图开始,介绍下concurrent包的用法。
java
总结几点如今知道的synchronized的异同,基本也就是个认知阶段,并不能说明真实的原理信息。之后有时间在详细的查阅官方资料:jvm
synchronized:
ide
一、JVM实现工具
二、能够经过工具监控
性能
三、自动释放
优化
四、在等待的的时候什么都不能干,只有等待唤醒(jvm唤醒、打断)
ui
lock:
this
一、代码实现、没法监控。释放在finally里面
spa
二、获取:能够明确知道结果。固然,也就能够作等待、或者直接作其余操做
线程
三、释放:以任何顺序获取和释放多个锁、释放方式和偏向锁相似
三、读写分离锁分离
lock的实现和偏向锁很相似,一个特色灵活,很是灵活。固然操做起来也更加困难,不过相信随着Oracle持续的释放黑科技优化jvm,synchronized性能愈来愈高。
lock的使用:
public interface Lock { //获取锁。若是锁不可用,出于线程调度目的,将禁用当前线程,而且在得到锁以前,该线程将一直处于休眠状态。 void lock(); //若是当前线程未被中断,则获取锁 void lockInterruptibly() throws InterruptedException; //仅在调用时锁为空闲状态才获取该锁。若是锁可用,则获取锁,并当即返回值 true。若是锁不可用,则此方法将当即返回值 false。 boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition(); }
其中lock的标准用法:若是拿不到锁就在队列中等待
Lock l = ...; l.lock(); try { // access the resource protected by this lock } finally { l.unlock(); }
tryLock的用法:若是没有获取锁,能够直接作其余的用处
Lock lock = ...; if (lock.tryLock()) { try { // manipulate protected state } finally { lock.unlock(); } } else { // perform alternative actions }
lockInterruptibly:获取一个带有中断处理的锁。例如:线程A获取了锁,则不能中断。线程B会一直循环,而后自旋不端获取锁,或者查询是否有中断指令。在AbstractQueuedSynchronizer源码中,doAcquireInterruptibly(int arg)方法能够看出,是经过抛出异常来终端获取锁,在使用的时候须要用try。
public void testInterrupted() throws InterruptedException { lock.lockInterruptibly(); try{ //TODO: }finally{ lock.unlock(); } }
例子:lock
public class lockTest implements Runnable { private Lock lock; public lockTest(Lock lock) { this.lock = lock; } @Override public void run() { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is begin"); lock.lock(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is over"); lock.unlock(); } } public static void main(String[] args) { Lock lock = new ReentrantLock(); // ExecutorService es = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) { new Thread(new lockTest(lock)).start(); ; } // es.shutdown(); } }
tryLock例子
public class TryLock implements Runnable { private Lock lock; public TryLock(Lock lock) { this.lock = lock; } @Override public void run() { if (lock.tryLock()) { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is begin"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is over"); lock.unlock(); } } else { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is not acquire"); } } public static void main(String[] args) { Lock lock = new ReentrantLock(); TryLock trylock = new TryLock(lock); new Thread(trylock).start(); new Thread(trylock).start(); } }
lockInterrupte:若是当前线程未被中断,则获取锁。
public class LockInterrupt implements Runnable { private Lock lock; public LockInterrupt(Lock lock) { this.lock = lock; } private void testInterrupt() { try { lock.lockInterruptibly(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " is begin"); // Thread.sleep(5000);// 睡眠阻塞、会被打断 // for (;;) { } } catch (InterruptedException e1) { e1.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " is over"); lock.unlock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " is release"); } } @Override public void run() { this.testInterrupt(); } public static void main(String[] args) { try { Lock lock = new ReentrantLock(); LockInterrupt li = new LockInterrupt(lock); Thread t1 = new Thread(li, "t1"); Thread t2 = new Thread(li, "t2"); t1.start(); t2.start(); Thread.sleep(500); t1.interrupt(); // t2.interrupt();// 会将t1的sleep直接打断、而后t2 } catch (InterruptedException e) { e.printStackTrace(); } } }
读写锁ReentrantReadWriteLock:读锁能够多个线程一块儿使用。写锁只能线程独享,这时候还会阻塞其它读锁、写锁
public class WritReadTest { private ReentrantReadWriteLock rrwl; public WritReadTest(ReentrantReadWriteLock lock) { this.rrwl = lock; } public void read() { try { rrwl.readLock().lock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " readlock is begin"); Thread.sleep(5000);// 睡眠阻塞、会被打断 } catch (InterruptedException e1) { e1.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " readlock is over"); rrwl.readLock().unlock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " readlock is release"); } } public void write() { try { rrwl.writeLock().lock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " write is begin"); Thread.sleep(5000);// 睡眠阻塞、会被打断 } catch (InterruptedException e1) { e1.printStackTrace(); } finally { System.out.println("Thread Name: " + Thread.currentThread().getName() + " write is over"); rrwl.writeLock().unlock(); System.out.println("Thread Name: " + Thread.currentThread().getName() + " write is release"); } } public static void main(String[] args) { ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock(); WritReadTest wrt = new WritReadTest(rrwl); new Thread(new ReadTest(wrt)).start(); new Thread(new WriteTest(wrt)).start(); } } class ReadTest implements Runnable { public WritReadTest wrt; public ReadTest(WritReadTest wrt) { this.wrt = wrt; } @Override public void run() { // wrt.read(); wrt.write(); } } class WriteTest implements Runnable { private WritReadTest wrt; public WriteTest(WritReadTest wrt) { this.wrt = wrt; } @Override public void run() { wrt.write(); // wrt.read(); } }
condition:条件。代替Object的监视方法(wait、notify、notifyAll)。直接经过代码将线程放入一个等待队列,而后等待其它线程唤醒。
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }