高并发编程:10、自定义锁,实现synchronized的设置超时

一、概述

  • 当有10个线程在调用一个被synchronized的方法时,只有当前拿到锁的线程执行完之后,其它9个线程才能有一个线程抢到锁。反复如此,如果方法固定调用时长为10秒,执行完成之后就是100秒。
  • 所以当我们调用这个方法的时候想要设置一个超时时间,超过之间就放弃调用。

二、代码

public class Thread13 {
	
	public static void main(String[] args) {
		final BooleanLock booleanLock = new BooleanLock();
		Thread thread1 = new Thread(new Runnable() {
			public void run() {
				try {
					booleanLock.lock();
					working();
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					booleanLock.unlock();
				}
			}
		},"t1");
		thread1.start();
		
		Thread thread2 = new Thread(new Runnable() {
			public void run() {
				try {
					booleanLock.lock();
					working();
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					booleanLock.unlock();
				}
			}
		},"t2");
		thread2.start();

		Thread thread3 = new Thread(new Runnable() {
			public void run() {
				try {
					booleanLock.lock();
					working();
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					booleanLock.unlock();
				}
			}
		},"t3");
		thread3.start();
		
		Thread thread4 = new Thread(new Runnable() {
			public void run() {
				try {
					booleanLock.lock(5*1000);
					working();
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch(TimeOutException e) {
					System.out.println(Thread.currentThread().getName() + " timeOut");
				} finally {
					booleanLock.unlock();
				}
			}
		},"t4");
		thread4.start();
	}
	
	public static void working() {
		try {
			System.out.println(Thread.currentThread().getName() + " working...");
			Thread.sleep(10*1000);
			System.out.println(Thread.currentThread().getName() + " working end");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 锁接口
	 * @author chenfenli
	 *
	 */
    public static interface Lock {
    	
    	class TimeOutException extends Exception {
			private static final long serialVersionUID = 1L;
			public TimeOutException(String message) {
    			super(message);
    		}
    	}
    	
    	/**
    	 * 加锁
    	 * @throws InterruptedException
    	 */
    	public void lock() throws InterruptedException;
    	
    	/**
    	 * 加锁
    	 * @param timeOut 超时时间 毫秒
    	 * @throws InterruptedException
    	 */
    	public void lock(long timeOut) throws InterruptedException,TimeOutException;
    	
    	/**
    	 * 释放锁
    	 */
    	public void unlock();
    	
    	/*
    	 * 获取处于wait状态中的锁
    	 */
    	public Collection getBlockedThread();
    	
    	/**
    	 * 获取处于wait状态中的锁的数量
    	 * @return
    	 */
    	public Integer getBlockedSize();
    }
    
    public static class BooleanLock implements Lock {
    	
    	public boolean flag = false;
    	
    	// 等待线程集合
    	public Collection blockedTheadList = new ArrayList();
    	
    	public Thread thisThread = null;
    	
		public synchronized void lock() throws InterruptedException {
			while (flag) {
				// 锁已被其它线程所用 -> 将对象设置为wait,释放锁,并加入到集合
				if(!blockedTheadList.contains(Thread.currentThread())) {
					blockedTheadList.add(Thread.currentThread());
				}
				System.out.println(Thread.currentThread().getName() + " wait 等待线程数:" + blockedTheadList.size());
				this.wait();
			} 
			System.out.println(Thread.currentThread().getName() + " start 等待线程数:" + blockedTheadList.size());
			flag = true;
			thisThread = Thread.currentThread();
		}
		
		public synchronized void lock(long timeOut) throws InterruptedException, TimeOutException {
			if(timeOut <= 0) {
				lock();
				return;
			}
			long endTime = System.currentTimeMillis() + timeOut;
			while (flag) {
				if(!blockedTheadList.contains(Thread.currentThread())) {
					blockedTheadList.add(Thread.currentThread());
				}
				System.out.println(Thread.currentThread().getName() + " timewait 等待线程数:" + blockedTheadList.size());
				if(System.currentTimeMillis() - endTime > 0) {
					blockedTheadList.remove(Thread.currentThread());
					throw new TimeOutException("timeOut");
				}
				this.wait(timeOut);
			}
			System.out.println(Thread.currentThread().getName() + " start 等待线程数:" + blockedTheadList.size());
			flag = true;
			thisThread = Thread.currentThread();
		}

		public synchronized void unlock() {
			if(thisThread == Thread.currentThread()) {
				blockedTheadList.remove(Thread.currentThread());
				flag = false;
				System.out.println(Thread.currentThread().getName() + " unlock 等待线程数:" + blockedTheadList.size());
				this.notifyAll();
			}
		}
		
		public Collection getBlockedThread() {
			return Collections.unmodifiableCollection(blockedTheadList);
		}
		
		public Integer getBlockedSize() {
			return blockedTheadList.size();
		}
    }
t1 start 等待线程数:0
t1 working...
t2 wait 等待线程数:1
t3 wait 等待线程数:2
t4 timewait 等待线程数:3
t4 timewait 等待线程数:3
t4 timeOut
t1 working end
t1 unlock 等待线程数:2
t3 start 等待线程数:2
t3 working...
t2 wait 等待线程数:2
t3 working end
t3 unlock 等待线程数:1
t2 start 等待线程数:1
t2 working...
t2 working end
t2 unlock 等待线程数:0

 

你可能感兴趣的:(高并发编程)