zoukankan      html  css  js  c++  java
  • 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();
    	}  
    }
    

      

  • 相关阅读:
    raid0
    GitHub 标星 11000+,阿里开源的微服务组件如何连续 10 年扛住双十一大促?
    写给大家看的“不负责任” K8s 入门文档
    快速迁移 Next.js 应用到函数计算
    轻松搭建基于 Serverless 的 Go 应用(Gin、Beego 举例)
    阿里巴巴副总裁肖力:云原生安全下看企业新边界——身份管理
    从零开始入门 K8s | K8s 安全之访问控制
    深度解读!阿里统一应用管理架构升级的教训与实践
    CNCF 2019 年度报告重磅发布 | 云原生生态周报 Vol. 41
    HTML+CSS技术实现网页滑动门效果
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/11147114.html
Copyright © 2011-2022 走看看