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

      

  • 相关阅读:
    关于返回上一页功能
    Mybatis Update statement Date null
    SQLite reset password
    Bootstrap Validator使用特性,动态(Dynamic)添加的input的验证问题
    Eclipse使用Maven2的一次环境清理记录
    Server Tomcat v7.0 Server at localhost failed to start
    PowerShell一例
    Server Tomcat v7.0 Server at libra failed to start
    商标注册英语
    A glance for agile method
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/11147114.html
Copyright © 2011-2022 走看看