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();
	}  
}

  

posted @ 2019-07-07 18:21  石shi  阅读(1543)  评论(0编辑  收藏  举报