Java線程讀寫鎖


  排他鎖和共享鎖:

讀寫鎖:既是排他鎖,又是共享鎖。讀鎖,共享鎖,寫鎖:排他鎖

讀和讀是不互斥的

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Demo {

	private Map<String, Object> map=new HashMap<>();
	private ReadWriteLock rwl=new ReentrantReadWriteLock();
	
	private Lock r=rwl.readLock();
	private Lock w=rwl.writeLock();
	
	public Object get(String key){
		r.lock();
		System.out.println(Thread.currentThread().getName()+"讀操作正在執行。。。");
		try {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return map.get(key);
		} finally{
		    r.unlock();
		    System.out.println(Thread.currentThread().getId()+"讀操作執行完畢。。。");
		}
	}
	public void put(String key,Object value){
		w.lock();
		System.out.println(Thread.currentThread().getName()+"寫操作在執行。。。");
		try {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			map.put(key, value);
		} finally  {
			w.unlock();
			System.out.println(Thread.currentThread().getName()+"寫操作執行完畢。。。");
		}
	}
}

  

public class Main {
	public static void main(String[] args) {
		Demo d=new Demo();
		d.put("key1", "value1");
		
//		new Thread(new Runnable() {
//			@Override
//			public void run() {
//				d.put("key1", "value1");
//			}
//		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println(d.get("key1"));
			}
		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println(d.get("key1"));
			}
		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println(d.get("key1"));
			}
		}).start();
		
//		new Thread(new Runnable() {
//			@Override
//			public void run() {
//				d.put("key3", "value3");
//			}
//		}).start();
	}
}

  讀寫鎖需要保存的狀態:

寫鎖重入的次數

讀鎖的個數

每個讀鎖重入的次數

鎖降級:是指寫鎖降為讀鎖  

在寫鎖沒有釋放的時候,獲取到讀鎖,在釋放寫鎖

鎖升級:

把讀鎖,升級為寫鎖

在讀鎖沒有釋放的時候,獲取到寫鎖,在釋放讀鎖

private volatile boolean isUpdate;
	
	public void readWrite(){
		r.lock();
		if(isUpdate){
			r.unlock();
			w.lock();
			map.put("XXX", "xxx");
			r.lock();
			w.unlock();
		}
		Object obj=map.get("XXX");
		System.out.println(obj);
		r.unlock();
	}

  出現線程安全性問題的條件

1.必須在多線程的環境下

2.必須有共享資源

3.對共享資源進行非原子性操作

       解決線程安全性問題的途徑

1.synchronized 相對慢(偏向鎖、輕量級鎖、重量級鎖)

2.volatile(只能保證讀寫操作,不能保證非原子性操作)

3.JDK提供的原子類

4.使用Lock(共享鎖、排它鎖)

       認識的“*鎖“

1.偏向鎖

2.輕量級鎖

3.重量級鎖

4.重入鎖

5.自旋鎖

6.共享鎖

7.獨占鎖

8.排它鎖

9.讀寫鎖

10.公平鎖

11.非公平鎖

12.死鎖

13.活鎖

public class Tmall {
    public int count;
    public final int MAX_COUNT=10;
    public synchronized  void push(){
    	while(count>=MAX_COUNT)
			try {
				System.out.println(Thread.currentThread().getName()+
						"庫存數量達到上限,生產者停止生產。");
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	count++;
    	System.out.println(Thread.currentThread().getName()
    			+"生產者生產,當前庫存為:"+count);
    	notify();
    }
    public synchronized void task(){
    	while(count<=0)
			try {
				System.out.println(Thread.currentThread().getName()+
						"庫存數量為零,消費着等待。");
				wait();
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
    	count--;
    	System.out.println(Thread.currentThread().getName()+
    			"消費者消費,當前庫存為:"+count);
    	notify();
    }
}

  

public class TaskTarget implements Runnable {
	private Tmall tmall;
	public  TaskTarget(Tmall tmall) {
		this.tmall=tmall;
	}
	@Override
	public void run() {
		tmall.task();
	}
}

  

public class PushTarget implements Runnable{
	private Tmall tmall;
	public   PushTarget(Tmall tmall) {
		this.tmall=tmall;
	}
	@Override
	public void run() {
		while(true){
			tmall.push();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
		}
		
	}
}

  

public class Main {
   public static void main(String[] args){
	   Tmall tmall=new Tmall();
	   PushTarget p=new PushTarget(tmall);
	   TaskTarget t=new TaskTarget(tmall);
	   
	   new Thread(p).start();
	   new Thread(p).start();
	   new Thread(p).start();
			   
	   new Thread(t).start();
	   new Thread(t).start();
	   new Thread(t).start();
   }
}

  Condition的使用。

public class Demo5 {
	private int signal;
	//執行順序 a->b->c
    public synchronized void a(){
    	while(signal!=0){
    		try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
    	}
    	System.out.println("a");
    	signal++;
    	notifyAll();
    }
    public synchronized void b(){
    	while(signal!=1){
    		try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
    	}
    	System.out.println("b");
    	signal++;
    	notifyAll();
    }
    public synchronized void c(){
    	while(signal!=2){
    		try {
				wait();
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
    	}
    	System.out.println("c");
    	signal=0;
    	notifyAll();
    }
    public static void main(String[] args){
    	Demo5 d=new Demo5();
    	A a=new A(d);
    	B b=new B(d);
    	C c=new C(d);
    	
    	new Thread(a).start();
    	new Thread(b).start();
    	new Thread(c).start();
    }
    
}

class A implements Runnable{
	private Demo5 demo;
	public A(Demo5 demo){
		this.demo=demo;
	}
	@Override
	public void run(){
		while(true){
			demo.a();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class B implements Runnable{
	private Demo5 demo;
	public B(Demo5 demo){
		this.demo=demo;
	}
	@Override
	public void run(){
		while(true){
			demo.b();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class C implements Runnable{
	private Demo5 demo;
	public C(Demo5 demo){
		this.demo=demo;
	}
	@Override
	public void run(){
		while(true){
			demo.c();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

  用condition

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

public class Demo {
	
	private int signal;
	
	Lock lock = new ReentrantLock();
	Condition a = lock.newCondition();
	Condition b = lock.newCondition();
	Condition c = lock.newCondition();
	
	
	public void a() {
		lock.lock();
		while(signal != 0 ) {
			try {
				a.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("a");
		signal ++;
		b.signal();
		lock.unlock();
	}
	
	public  void b() {
		lock.lock();
		while(signal != 1) {
			try {
				b.await();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("b");
		signal ++;
		c.signal();
		lock.unlock();
	}
	
	public  void c () {
		lock.lock();
		while(signal != 2) {
			try {
				c.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("c");
		signal = 0;
		a.signal();
		lock.unlock();
	}
	
	public static void main(String[] args) {
		
		Demo d = new Demo();
		A a = new A(d);
		B b = new B(d);
		C c = new C(d);
		
		new Thread(a).start();
		new Thread(b).start();
		new Thread(c).start();
		
	}
}

class A implements Runnable {
	
	private Demo demo;
	
	public A(Demo demo) {
		this.demo = demo;
	}

	@Override
	public void run() {
		while(true) {
			demo.a();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}
class B implements Runnable {
	
	private Demo demo;
	
	public B(Demo demo) {
		this.demo = demo;
	}
	
	@Override
	public void run() {
		while(true) {
			demo.b();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}
class C implements Runnable {
	
	private Demo demo;
	
	public C(Demo demo) {
		this.demo = demo;
	}
	
	@Override
	public void run() {
		while(true) {
			demo.c();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}	
}

  實現一個隊列:

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

public class MyQueue<E> {
	private Object[] obj;
    private int addIndex;
    private int removeIndex;
    private int queueSize;
    
    private Lock lock=new ReentrantLock();
    Condition addCondition=lock.newCondition();
    Condition removeCondition=lock.newCondition();
    
	public MyQueue(int count){
		obj=new Object[count];
	}
    public void add(E e){
    	lock.lock();
    	//滿了之后等待
    	while(queueSize==obj.length){
    		try {
				addCondition.await();
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
    	}
	  obj[addIndex]=e;
	  if(++addIndex==obj.length){ //先比較在++
		  addIndex=0;
	  }
	  queueSize++;
	  removeCondition.signal();
	  lock.unlock();
   }
    public void remove(){
    	lock.lock();
    	while (queueSize==0) {
    		try {
				removeCondition.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		obj[removeIndex]=null;
		if(++removeIndex==obj.length){
			removeIndex=0;
		}
		queueSize--;
		addCondition.signal(); 
		lock.unlock();
	}  
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM