• JDK提供的原子类和AbstractQueuedSynchronizer(AQS)


    大致分成:

    1.原子更新基本类型

    2.原子更新数组

    3.原子更新抽象类型

    4.原子更新字段

    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.concurrent.atomic.AtomicIntegerArray;
    import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
    import java.util.concurrent.atomic.AtomicReference;
    
    public class Sequence {
    	private AtomicInteger value=new AtomicInteger(0);
    	private int [] s={2,1,4,6}; 
    	AtomicIntegerArray array=new AtomicIntegerArray(s);
    	
    	AtomicReference<User> use=new AtomicReference<>();
    	
    	AtomicIntegerFieldUpdater<User> old=
    			AtomicIntegerFieldUpdater.newUpdater(User.class, 
    					"old");
    
    	public int getNext(){
    		User user=new User();
    		System.out.println(old.getAndIncrement(user));
    		System.out.println(old.getAndIncrement(user));
    		System.out.println(old.getAndIncrement(user));
    		old.getAndIncrement(user);
    		array.getAndIncrement(2);
    		array.getAndAdd(2, 10);
    		return value.getAndIncrement();//自增value++
    		//value.incrementAndGet();//++value
    	}
    	public static void main(String[] args) {
    		Sequence s=new Sequence();
    		new Thread(new Runnable() {
    			
    			@Override
    			public void run() {
    				System.out.println(Thread.currentThread().getName()+""
    			+s.getNext());
    				try {
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    					
    					e.printStackTrace();
    				}
    			}
    			
    		}).start();
    //      new Thread(new Runnable() {
    //			
    //			@Override
    //			public void run() {
    //				System.out.println(Thread.currentThread().getName()+""
    //			+s.getNext());
    //				try {
    //					Thread.sleep(100);
    //				} catch (InterruptedException e) {
    //					
    //					e.printStackTrace();
    //				}
    //			}
    //			
    //		}).start();
    	}
    }
    

      Lock接口:

    Lock需要显示的获取和释放锁,繁琐,但是能让代码更灵活,随时,获取和释放锁

    Synchronized:不需要显示的获取和释放锁 ,简单

    使用lock可以方便的实现公平性

    非阻塞的获取锁

    能被中断的获取锁

    超时获取锁

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Sequence {
    	private int value;
    	Lock lock=new ReentrantLock();//所有的线程公用一把锁
    	public int getNext() {
    		lock.lock();
    		int a= value++;
    		lock.unlock();
            return a;
    	}
    
    	public static void main(String[] args) {
    		Sequence s = new Sequence();
    		new Thread(new Runnable() {
    
    			@Override
    			public void run() {
    				while (true) {
    					System.out.println(Thread.currentThread().getName() + "" + s.getNext());
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    			}
    
    		}).start();
    
    		new Thread(new Runnable() {
    
    			@Override
    			public void run() {
    				while (true) {
    					System.out.println(Thread.currentThread().getName() + "" + s.getNext());
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    			}
    
    		}).start();
    
    		new Thread(new Runnable() {
    
    			@Override
    			public void run() {
    				while (true) {
    					System.out.println(Thread.currentThread().getName() + "" + s.getNext());
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    			}
    
    		}).start();
    	}
    }
    

      实现一个锁的重入:

    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    
    public class MyLock implements Lock{
    
    	private boolean isLocked=false;	
    	private Thread lockBy=null;
    	private int lockCount=0;
    	@Override
    	public synchronized void lock() {
    		//Thread.activeCount()
    		Thread currentThread=Thread.currentThread();//获取当前线程
    		while(isLocked &&currentThread!=lockBy){ //不相等,等待
    			try {
    				wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			isLocked=true;
    			lockBy=currentThread;
    			lockCount++;
    		}
    	}
    
    	@Override
    	public synchronized void unlock() {
    		if(lockBy==Thread.currentThread()){
    			lockCount--;
    			if(lockCount==0){
    				notify();
    				isLocked=false;
    			}
    		}
    	}
    	@Override
    	public void lockInterruptibly() throws InterruptedException {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public Condition newCondition() {
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    	@Override
    	public boolean tryLock() {
    		// TODO Auto-generated method stub
    		return false;
    	}
    
    	@Override
    	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
    		// TODO Auto-generated method stub
    		return false;
    	}
    }
    

      

    public class Demo {
    	MyLock lock=new MyLock();	
       public void a(){
    	   lock.lock();
    	   System.out.println("a");
    	   b();
    	   lock.unlock();
       }
       public void b(){
    	   lock.lock();
    	   System.out.println("b");
    	   lock.unlock();
       }
       public static void main(String[] args) {
    	  Demo demo=new Demo();
    	  new Thread(new Runnable() {
    		@Override
    		public void run() {
    			demo.a();
    		}
    	}).start();
       }
    }
    

      AbstractQueuedSynchronizer(AQS)

    开发文档:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

    公平锁:

    公平锁是对锁的获取而言,如果一个锁是公平的,那么锁的获取顺序就是应该符合请求的绝对时间顺序。

    import java.util.ArrayList;
    import java.util.List;
    
    public class FairLock {
    	private boolean isLocked=false;
    	private Thread lockingThread=null;
    	private List<QueueObject> waitingThreads=new ArrayList<QueueObject>();
    	
    	private void lock() throws InterruptedException{
    		QueueObject queueObject=new QueueObject();
    		synchronized (this) {
    		    waitingThreads.add(queueObject);
    		}
    		try {
    			queueObject.doWait();
    		} catch (InterruptedException e) {
    			synchronized (this) {
    				waitingThreads.remove(queueObject);
    			}
    			throw e;
    		}
    	}
    
    	public synchronized void unlock(){
    		if(this.lockingThread!=Thread.currentThread()){
    			throw new IllegalMonitorStateException("Calling thread has not locked this lock");
    		}
    		isLocked=false;
    		lockingThread=null;
    		if(waitingThreads.size()>0){
    			waitingThreads.get(0).doNotify();
    		}
    	}
    }
    

      

    public class QueueObject {
    	private boolean isNotified=false;
    	public synchronized void doWait() throws InterruptedException{
    		while(!isNotified){
    			this.wait();
    		}
    		this.isNotified=false;
    	}
    	public synchronized void doNotify(){
    		this.isNotified=true;
    		this.notify();
    	}
    	public boolean equals(Object o){
    		return this==o;
    	}
    }
    

      aqs实现锁重入:

    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.AbstractQueuedSynchronizer;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    
    public class MyLock2 implements Lock{
    	private Helper helper=new Helper();
    	private class Helper extends AbstractQueuedSynchronizer{
    	   @Override
    	   protected boolean tryAcquire(int arg){
    		   //如果第一个线程进来,可以拿到锁,可以返回true
    		   
    		   //第二个线程进来,拿不到锁,返回false.有种特列,
    		   //如果当前进来的线程的和当前保存的线程是同一个线程,则可以拿到锁,但是有代价。要更新状态的值
    		   
    		   //如何判断是第一个线程进来,还是其他线程
    		   int state=getState();
    		   Thread t=Thread.currentThread();
    		   if(state==0){
    			   if(compareAndSetState(0, arg)){
    				   setExclusiveOwnerThread(Thread.currentThread());
    				   return true;
    			   }
    		   }else if(getExclusiveOwnerThread()==t){
    			setState(state+1);
    			return true;
    		}
    		   
    		   return false;
    	   }
    	   @Override
    	   protected boolean tryRelease(int arg){
    		   //锁的获取和释放肯定是一一对应的,那么调用此方法的线程一定是当前线程
    		   if(Thread.currentThread()!=getExclusiveOwnerThread()){
    			   throw new RuntimeException();
    		   }
    		   int state=getState()-arg;
    		   boolean flag=false;
    		   if(getState()==0){
    			   setExclusiveOwnerThread(null);
    			   flag=true;
    		   }
    		   setState(state);
    		   return flag;
    	   }
    	   Condition newCondition(){
    		   return new ConditionObject();
    	   }
    	}
    	
    	@Override
    	public void lock() {
    		helper.acquire(1);
    	}
    
    	@Override
    	public void lockInterruptibly() throws InterruptedException {
    		helper.acquireInterruptibly(1);
    	}
    
    	@Override
    	public Condition newCondition() {
    		return helper.newCondition(); 
    	}
    
    	@Override
    	public boolean tryLock() {
    		return helper.tryAcquire(1);
    	}
    
    	@Override
    	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
    		return helper.tryAcquireNanos(1, unit.toNanos(time));
    	}
    
    	@Override
    	public void unlock() {
    		helper.release(1);
    	}
    
    }
    

      

    public class Main {
    	private int value;
    	private MyLock2 lock=new MyLock2();
    	public int next(){
    		lock.lock();
    		try {
    			Thread.sleep(300);
    			return value++;
    		} catch (InterruptedException e) {
    			throw new RuntimeException();
    		}finally {
    			lock.unlock();
    		}
    	}
    	public void a(){
    		lock.lock();
    		System.out.println("a");
    		b();
    		lock.unlock();
    	}
    	public void b(){
    		lock.lock();
    		System.out.println("b");
    		lock.unlock();
    	}
    	public static void main(String[] args) {
    		Main m=new Main();
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				m.a();
    			}
    		}).start();
    //		new Thread(new Runnable() {
    //			@Override
    //			public void run() {
    //				while(true){
    //					System.out.println(Thread.currentThread().getId()
    //							+""+ m.next());
    //				}
    //			}
    //		}).start();
    //		new Thread(new Runnable() {
    //			@Override
    //			public void run() {
    //				while(true){
    //					System.out.println(Thread.currentThread().getId()
    //							+""+ m.next());
    //				}
    //			}
    //		}).start();
    	}
    
    }
    
  • 相关阅读:
    HP SAN Switch參考文檔地址
    hp,Qlogic,Brocade光纖卡查看方式
    使用nbrbutil工具來處理requested media id is in use, cannot process request
    NBU expired Media,Media ID not found in EMM database
    訪問索引的方法
    Linux光纖卡配置,磁盤掛載,多路徑設置
    Linux 6.5網卡配置
    Oracle ASM
    NBU bplabel命令擦除磁帶數據
    鼠标悬浮显示完整信息
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/11143600.html
Copyright © 2020-2023  润新知