java的concurrent包簡介

java的concurrent包簡介

        java的concurrent包中的鎖lock;工具類:CyclicBarrier、semaphore、CountDownLatch;集合:blockingquue、concurrentMap;原子量:aotmic。先從下面的圖開始,介紹下concurrent包的用法。
java

一、lock類

       總結幾點如今知道的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();
     }
   } 
 }
相關文章
相關標籤/搜索