java中的互斥鎖,訊號量和多執行緒等待機制
阿新 • • 發佈:2019-02-15
互斥鎖和訊號量都是作業系統中為併發程式設計設計基本概念,互斥鎖和訊號量的概念上的不同在於,對於同一個資源,互斥鎖只有0和1 的概念,而訊號量不止於此。也就是說,訊號量可以使資源同時被多個執行緒訪問,而互斥鎖同時只能被一個執行緒訪問
互斥鎖在java中的實現就是 ReetranLock , 在訪問一個同步資源時,它的物件需要通過方法 tryLock() 獲得這個鎖,如果失敗,返回 false,成功返回true。根據返回的資訊來判斷是否要訪問這個被同步的資源。看下面的例子
public class ReentranLockExample { private static int count = 0; private static ReentrantLock reentrantLock = new ReentrantLock(); static class MyThread extends Thread{ @Override public void run() { super.run(); try { while (true){ boolean result = reentrantLock.tryLock(); if (result){ System.out.println(Thread.currentThread().getName() + "get the lock success and run the syn code " + count ++); reentrantLock.unlock(); }else{ System.out.println(Thread.currentThread().getName() + "get the lock failed and run the syn code " + count); } System.out.println(Thread.currentThread().getName() + "run the asyntronized code " + count); Thread.sleep(500); } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args){ MyThread thread1 = new MyThread(); MyThread thread2 = new MyThread(); thread1.start(); thread2.start(); } }
訊號量相當於一個計數器,如果執行緒想要訪問某個資源,則先要獲得這個資源的訊號量,並且訊號量內部的計數器減1 ,訊號量內部的計數器大於0則意味著有可以使用的資源,當執行緒使用完某個資源時,必須釋放這個資源的訊號量。訊號量的一個作用就是可以實現指定個執行緒去同事訪問某個資源。只需要在初始化 。
訊號量在 Java中的實現是 Semaphore ,其在初始化時傳入一個整型數, 用來指定同步資源最大的併發訪問量
public class SemaphoreExample { private static Semaphore semaphore = new Semaphore(2); private String lock = "lock"; private static int count = 0; static class MyThread extends Thread { @Override public void run() { super.run(); try { while (true) { semaphore.acquire(); Thread.sleep(500); System.out.println(Thread.currentThread().getName() + "get the lock success and run the syn code " + count++); semaphore.release(); Thread.sleep(500); } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args){ MyThread thread1 = new MyThread(); MyThread thread2 = new MyThread(); MyThread thread3 = new MyThread(); thread1.start(); thread2.start(); thread3.start(); } }
CountDownLatch 實現一個等待機制,在諸如 等待與會者到達後,開始會議的使用中。ConutDownLatch 在初始化中一個計數器,用來指定需要等待的個數。在併發程式設計中,所解決的需求就是,等待所有的執行緒到達某個點後。才開始進行下一步,有點類似於開會,只有當所有的與會人員都到齊後,會議才能開始
public class CountDownLatchExample { private static CountDownLatch mCountDownLatch = new CountDownLatch(3); static class MyThread extends Thread { int awaitTime; public MyThread(int i) { this.awaitTime = i; } @Override public void run() { super.run(); try { while (true) { Thread.sleep(awaitTime); System.out.println(Thread.currentThread().getName() + "arrived " ); mCountDownLatch.countDown(); mCountDownLatch.await(); //可以指定等待時間 System.out.println(Thread.currentThread().getName() + "start meeting " ); } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args){ MyThread thread1 = new MyThread(500); MyThread thread2 = new MyThread(1000); MyThread thread3 = new MyThread(2000); thread1.start(); thread2.start(); thread3.start(); } }