Java concurrent programming principles (V)

LK then continue contents of the above summary of knowledge, new year wish I could continue to update their technology stack, I also wish you browse the home page of the new year friend promotion and pay rise.

Fair locks

1. Why should there be fair locks?

是因为出现了不公平--java中称之为饥饿。

> 如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为“饥饿”。

Summary: cpu because their running time is occupied by other threads.

2.Java the causes of hunger

  • High-priority thread CPU time to devour all of the low priority thread. (Thread priority)
  • Thread is blocked permanently in a state of waiting to enter the synchronized block, because the other thread is always the synchronization can continue to block access to it before. (Java synchronization code area on which thread is allowed to enter the order without any protection)
  • In a thread waiting for itself (on its call to wait ()) is also in perpetual wait for the completion of the object, because the other threads are always constantly get wake. (Multiple threads call wait () method, using a method nofity wake one of them uncertain, there is always a not wake up)

Lock the principle of fair

Here Insert Picture Description

public class QueueObject {
	private boolean flag=false;
	public synchronized void doWait() throws InterruptedException {
		//自旋,
		while (!flag) {
			this.wait();
		}
		flag=false;
	}
	
	public synchronized void doNotify() {
		flag=true;
		this.notify();
	}
	
	@Override
	public boolean equals(Object obj) {
		return this==obj;
	}
}

public class FairLock {
	// private boolean flag=false;
	private Thread currenThread = null;
	List<QueueObject> queueList = new ArrayList<QueueObject>();

	private void MyLock() {
		QueueObject objectQueue = new QueueObject();
		currenThread = Thread.currentThread();
		synchronized (this) {
			queueList.add(objectQueue);
		}
		try {
			objectQueue.doWait();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			synchronized (this) {
				queueList.remove(objectQueue);
			}
		}

	}

	private void MyUnlock() {
		if (currenThread != Thread.currentThread())
			throw new IllegalMonitorStateException("Calling thread has not locked this lock");
		else
			currenThread = null;
		if (queueList.size() > 0) {
			queueList.get(0).doNotify();
		}
	}

}

The main internal maintains a queue, the first thread in the queue after you have added an element, other threads are finished adding elements will spin blocks, waiting for the head of the queue elements wake. The next element entered, the application can be seen queuing mechanism is still quite extensive.

Read-Write Lock

1. What is the read-write lock?
Read-Write Lock is a special kind of spin lock, it is the shared resources of the visitors became divided readers and writers,Readers only access to shared resourcesWriter is to write to the shared resource .
Read-write locks can at the same time
Allows multiple threads read access
But when writing thread access, all the threads read and write other threads are blocked. Read-Write Lock maintains a lock, a lock and a read-write locks, read by separating and write locks, making concurrency compared to the general exclusive lock has been greatly improved
2. Use the scene?
Read operations than write operations
3. Simple examples

public class MyReadWriteLock {


		private ReadWriteLock rwl = new ReentrantReadWriteLock();

		private Map<String, Object> map = new HashMap<>();

		public void setMap(String string, Object object) {
			rwl.writeLock().lock();
			System.out.println(Thread.currentThread().getName() + " 写操作在执行..");
			try {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				map.put(string, object);
			} finally {
				rwl.writeLock().unlock();
				System.out.println(Thread.currentThread().getName() + " 写操作执行完毕");
			}
		}

		public Object getMap(String key) {
			rwl.readLock().lock();
			System.out.println(Thread.currentThread().getName() + " 读操作在执行..");
			try {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return map.get(key);

			} finally {
				rwl.readLock().unlock();
				System.out.println(Thread.currentThread().getName() + " 读操作执行完毕");
			}

		}
	 
}

	public static void main(String args[]) {
		
		MyReadWriteLock lock=new MyReadWriteLock();
		lock.setMap("aa", "xxxxx");
		ExecutorService service = Executors.newFixedThreadPool(20);
		for (int i = 0; i < 20; i++) {
			service.execute(new Runnable() {
				@Override
				public void run() {
					System.out.println(
							Thread.currentThread().getName() + "..." +lock.getMap("aa"));
				}
			});
		}

	}

4. The read-write lock release and access to
summarize: Each release were reduced write state, for a write lock has been released, so that the waiting thread can continue to read and write access to read and write when the write lock state is zero, and last write thread modify visible to follow the thread to read and write.
Read locks are released each time (thread-safe, there may be multiple threads simultaneously read the release read lock) to reduce the read status
after the analysis of AQS Further Discussion
5. Lock downgrade
process: obtain a write lock, and then to get a read lock, then release (previously owned) write lock process
Objective: self-perception is to reduce the write lock hold and improve performance.

public class LockDown {

   private Map<String, Object> map = new HashMap<>();

   private ReadWriteLock rwl = new ReentrantReadWriteLock();

   private Lock r = rwl.readLock();
   private Lock w = rwl.writeLock();

   private volatile boolean isUpdate = false;

   public void readWrite() {
   	r.lock(); // 为了保证isUpdate能够拿到最新的值
   	if (!isUpdate) {
   		r.unlock();
   		w.lock();
   		try {
   			if (!isUpdate) {
   				// 准备数据的
   				map.put("asdsaf", "12314");
   			}
   			r.lock();// 获取读锁,保证数据的可见性。
   			// 直接释放写锁,会导致其他线程对数据进行跟新但是当前线程无法感知
   			// 获取读锁后其他线程会被阻塞,直到当前线程使用数据后,其它线程才可以获取。
   		} finally {
   			w.unlock();
   		}
   	}

   	try {
   		// 使用数据
   		Object obj = map.get("asdsaf");

   		System.out.println(obj);
   	} finally {
   		r.unlock();
   	}

   }

   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().getName() + " 读操执行完毕..");
   	}
   }

   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 static void main(String[] args) {
   	LockDown lockDown = new LockDown();
   	new Thread(new Runnable() {
   		@Override
   		public void run() {
   			lockDown.readWrite();
   		}
   	}).start();
   	new Thread(new Runnable() {
   		@Override
   		public void run() {
   			lockDown.readWrite();
   		}
   	}).start();
   	new Thread(new Runnable() {
   		@Override
   		public void run() {
   			lockDown.readWrite();
   		}
   	}).start();
   	new Thread(new Runnable() {
   		@Override
   		public void run() {
   			lockDown.readWrite();
   		}
   	}).start();
   	 
   }

}
Published 47 original articles · won praise 18 · views 5725

Guess you like

Origin blog.csdn.net/yuruizai110/article/details/87103534