【Java高併發學習】重入鎖ReentrantLock、Condition條件及信號量

Java重入鎖、Condition、信息量


1.重入鎖

import java.util.concurrent.locks.ReentrantLock;

/**
 * 重入鎖
 * @author wsz
 * @date 2017年12月2日
 */
public class ReentertLock implements Runnable{
	public static ReentrantLock lock = new ReentrantLock();//重入鎖
	public static long count =0L;
	
	public static void main(String[] args) throws InterruptedException {
		ReentertLock reentertLock = new ReentertLock();
		Thread t1 = new Thread(reentertLock);//接口構造函數
		Thread t2 = new Thread(reentertLock);
		t1.start();t2.start();
		t1.join();t2.join();
		System.out.println(count);
	}

	@Override
	public void run() {
		for (int i = 0; i < 10000; i++) {
			lock.lock();//加鎖
			count++;
			lock.unlock();//解鎖,次數必須與加鎖次數一致,否則將導致
		}
	}
}

2.重入鎖中斷請求

import java.util.concurrent.locks.ReentrantLock;

/**
 * 重入鎖之中斷鎖請求
 * 1.提供死鎖環境
 * 2.結束死鎖
 * 3.被中斷線程無法完成任務
 * @author wsz
 * @date 2017年12月2日
 */
public class IntLock implements Runnable{
	
	public static ReentrantLock lock1 = new ReentrantLock();//重入鎖
	public static ReentrantLock lock2 = new ReentrantLock();//重入鎖
	//控制加鎖順序,用於創造死鎖
	private int lock;	

	public IntLock(int lock) {
		super();
		this.lock = lock;
	}

	public static void main(String[] args) throws InterruptedException {
		IntLock intLock1 = new IntLock(1);
		IntLock intLock2 = new IntLock(2);
		Thread t1 = new Thread(intLock1);//t1先佔有鎖lock1,再請求lock2
		Thread t2 = new Thread(intLock2);//t2先佔有lock2,再請求lock1
		t1.start();t2.start();//開啓後形成死鎖
		Thread.sleep(2000);
		t2.interrupt();//中斷t2,t1將執行結束,t2放棄並結束
	}

	@Override
	public void run() {
		try {
			if(lock == 1) {                                
				lock1.lockInterruptibly();//在等待鎖時可以響應中斷
				try {
					Thread.sleep(1000);
				}catch (InterruptedException e) {}
				lock2.lockInterruptibly();//在等待鎖時可以響應中斷
			}else {
				lock2.lockInterruptibly();//在等待鎖時可以響應中斷
				try {
					Thread.sleep(1000);
				}catch (InterruptedException e) {}
				lock1.lockInterruptibly();//在等待鎖時可以響應中斷
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			if(lock1.isHeldByCurrentThread()) {//Queries if this lock is held by the current thread. 
				lock1.unlock();
			}
			if(lock2.isHeldByCurrentThread()) {//判斷當前線程是否擁有該鎖
				lock2.unlock();
			}
			System.out.println(Thread.currentThread().getId()+"線程退出");
		}
	}

}

3.Condition條件


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 重入鎖與Condition
 * @author wsz
 * @date 2017年12月2日
 */
public class ConditionLock implements Runnable{
	public static ReentrantLock lock = new ReentrantLock();//重入鎖
	public static Condition condition = lock.newCondition();//綁定相關的Condition實例
	
	@Override
	public void run() {
		try {
			lock.lock();
			condition.await();//等待並釋放鎖
			System.out.println("aaa");
		}catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	public static void main(String[] args) throws InterruptedException {
		ConditionLock cl = new ConditionLock();
		Thread t1 = new Thread(cl);
		t1.start();
		Thread.sleep(2000);
		lock.lock();
		condition.signal();//喚醒等待在Condition上的線程
		lock.unlock();//解鎖之後,將打印,否則無法執行。
	}
}

4.信號量Semaphore

  信號量提供多個線程來同時訪問某一個資源。內部鎖synchronized和重入鎖ReentrantLock一次都只允許一個線程訪問一個資源。


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * 信號量
 * @author wsz
 * @date 2017年12月2日
 */
public class SemaphoreTest implements Runnable{
	//型號量准入數、是否公平鎖;設置爲3將以每3個線程一組打印信息
	final Semaphore semp = new Semaphore(3, false);
	
	public static void main(String[] args) {
		ExecutorService exec = Executors.newFixedThreadPool(20);//開啓保護20個線程的線程池
		SemaphoreTest demo = new SemaphoreTest();
		for(int i=0 ;i <50 ;i++) {
			exec.submit(demo);
		}
	}

	@Override
	public void run() {
		try {
			semp.acquire(); //嘗試獲得一個准入的許可,如無法獲得將等待,直到獲得一個許可或者當前線程被中斷
			Thread.sleep(2000);//模擬耗時
			System.out.println(Thread.currentThread().getId()+":ok ok");
			semp.release();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章