`
chenzehe
  • 浏览: 538193 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

面试题——在多线程环境下如何保证一个List集合中的元素不超过15个

 
阅读更多

这是有一次去面试被问到的,当时只知道用synchronized来保证同步,但面试官说除了此方式的其它实现,现在写下它的各种实现:

1、JDK1.5之前的内置锁synchronized实现

 模仿JDK1.5之前同步集合SynchronizedList的实现,内部使用synchronized对一个对一个List的封装,如下代码:

/**
 * @description
 * 
 * @author chenzehe
 * @email hljuczh@163.com
 * @create 2013-2-22 下午05:03:43
 */
public class SyncList<E> implements List<E> {
	final Object	mutex;
	final List<E>	list;
	final int		fixSize;	
	public SyncList(List list, int fixSize) {
		super();
		mutex = this;
		this.list = list;
		this.fixSize = fixSize;
	}	
	@Override
	public boolean add(E e) {
		synchronized (mutex) {
			if (list.size() < fixSize) {
				System.out.println("add成功,size=" + list.size());
				return list.add(e);
			}
			else {
				System.out.println("大小已超过fixSize,不能再add...");
				return false;
			}
		}
		
	}	
	@Override
	public E remove(int index) {
		synchronized (mutex) {
			if (list.size() > 0) {
				System.out.println("删除成功...");
				return list.remove(index);
			}
			else {
				return null;
			}
		}
	}
        ......
}

 测试类,模拟几个线程对该集合进行操作:

/**
 * @description
 * 
 * @author chenzehe
 * @email hljuczh@163.com
 * @create 2013-2-22 下午05:49:40
 */
public class SyncListTest {	
	public static void main(String[] args) {
		int fixSize = 10;
		SyncList<Integer> syncList = new SyncList<Integer>(new ArrayList<Integer>(), fixSize);
		AddThread addThread = new AddThread(syncList);
		RemoveThread removeThread = new RemoveThread(syncList);
		new Thread(addThread).start();
		new Thread(addThread).start();
		new Thread(removeThread).start();
	}	
}

class AddThread implements Runnable {
	private SyncList<Integer>	syncList;
	
	public AddThread(SyncList<Integer> syncList) {
		this.syncList = syncList;
	}	
	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			syncList.add(i);
			try {
				Thread.sleep(100);
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class RemoveThread implements Runnable {
	private SyncList<Integer>	syncList;
	
	public RemoveThread(SyncList<Integer> syncList) {
		this.syncList = syncList;
	}
	
	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			syncList.remove(0);
			try {
				Thread.sleep(300);
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}

 输出:

add成功,size=0
add成功,size=1
删除成功...
add成功,size=1
add成功,size=2
add成功,size=3
add成功,size=4
删除成功...
add成功,size=4
add成功,size=5
add成功,size=6
add成功,size=7
add成功,size=8
add成功,size=9
大小已超过fixSize,不能再add...
大小已超过fixSize,不能再add...
删除成功...
add成功,size=9
大小已超过fixSize,不能再add...
... 

 2、JDK1.5之前的显示锁,并使用Condition控制当集合中的元素达到最大时使线程等待,如下代码:

 

/**
 * @description
 * 
 * @author chenzehe
 * @email hljuczh@163.com
 * @create 2013-2-22 下午06:43:06
 */

public class ReentrantLockList<E> implements List<E> {
	final List<E>				list;
	final int					fixSize;
	
	private final ReadWriteLock	lock		= new ReentrantReadWriteLock();
	private final Lock			r			= lock.readLock();
	private final Lock			w			= lock.writeLock();
	final Condition				notFull		= w.newCondition();
	final Condition				notEmpty	= w.newCondition();
	
	public ReentrantLockList(List<E> list, int fixSize) {
		super();
		this.list = list;
		this.fixSize = fixSize;
	}
	
	@Override
	public boolean add(E e) {
		boolean addResult = false;
		w.lock();
		try {
			while (list.size() >= fixSize) {
				System.out.println("大小已超过fixSize不能再添加,在等待中...");
				notFull.await();// Causes the current thread to wait until it is signalled or interrupted
			}
			addResult = list.add(e);
			System.out.println("add成功,size=" + list.size());
			notEmpty.signal();// Wakes up one waiting thread
		}
		catch (InterruptedException e2) {
			e2.printStackTrace();
		}
		finally {
			w.unlock();
		}
		return addResult;
	}
	
	@Override
	public E remove(int index) {
		E removeResult = null;
		w.lock();
		try {
			while (list.size() < 1) {
				System.out.println("集合为空不能删除,在等待中...");
				notEmpty.await();// Causes the current thread to wait until it is signalled or interrupted
			}
			removeResult = list.remove(index);
			System.out.println("删除成功...");
			notFull.signal();// Wakes up one waiting thread
		}
		catch (InterruptedException e2) {
			e2.printStackTrace();
		}
		finally {
			w.unlock();
		}
		return removeResult;
		
	}
	......
}
 测试类模拟几个线程同时对该集体进行操作:

 

 

/**
 * @description
 * 
 * @author chenzehe
 * @email hljuczh@163.com
 * @create 2013-2-22 下午07:04:50
 */

public class ReentrantLockListTest {
	
	public static void main(String[] args) {
		int fixSize = 10;
		ReentrantLockList<Integer> reentrantLockList = new ReentrantLockList<Integer>(new ArrayList<Integer>(), fixSize);
		AddReentrantLockListThread addThread = new AddReentrantLockListThread(reentrantLockList);
		RemoveReentrantLockListThread removeThread = new RemoveReentrantLockListThread(reentrantLockList);
		new Thread(addThread).start();
		new Thread(addThread).start();
		new Thread(removeThread).start();		
	}
	
}

class AddReentrantLockListThread implements Runnable {
	private ReentrantLockList<Integer>	reentrantLockList;
	
	public AddReentrantLockListThread(ReentrantLockList<Integer> reentrantLockList) {
		this.reentrantLockList = reentrantLockList;
	}
	
	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			reentrantLockList.add(i);
			try {
				Thread.sleep(100);
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class RemoveReentrantLockListThread implements Runnable {
	private ReentrantLockList<Integer>	reentrantLockList;
	
	public RemoveReentrantLockListThread(ReentrantLockList<Integer> reentrantLockList) {
		this.reentrantLockList = reentrantLockList;
	}
	
	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			reentrantLockList.remove(0);
			try {
				Thread.sleep(300);
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}
 

 

 输出结果:

 

集合为空不能删除,在等待中...
add成功,size=1
add成功,size=2
删除成功...
add成功,size=2
add成功,size=3
add成功,size=4
add成功,size=5
add成功,size=6
删除成功...
add成功,size=6
add成功,size=7
add成功,size=8
add成功,size=9
add成功,size=10
大小已超过fixSize不能再添加,在等待中...
删除成功...
add成功,size=10
大小已超过fixSize不能再添加,在等待中...
大小已超过fixSize不能再添加,在等待中...
删除成功...
add成功,size=10
大小已超过fixSize不能再添加,在等待中...
...
 

 

 

 

 

 

 

分享到:
评论

相关推荐

    Java全能学习面试手册——Java面试题库.zip

    08 15道面试常问的Java多线程面试题!.pdf 09 17道消息队列Kafka面试题!.pdf 10 18道非常牛逼的Nginx面试题!.pdf 11 20道顶尖的Spring Boot面试题!.pdf 12 20道面试官常问的JVM面试题!.pdf 13 22道面试常问的...

    115个Java面试题和答案——终极列表

    Java面试题是每个Java开发者在求职过程中必须面对的挑战,涵盖范围广泛,从基础概念到高级特性和设计模式。这份终极列表包含115个Java面试题和答案,旨在帮助求职者全面准备,以期在面试中表现出色。以下是部分核心...

    Java全能学习面试手册——Java架构师进阶资料面试资料.zip

    08 15道面试常问的Java多线程面试题!.pdf 09 17道消息队列Kafka面试题!.pdf 10 18道非常牛逼的Nginx面试题!.pdf 11 20道顶尖的Spring Boot面试题!.pdf 12 20道面试官常问的JVM面试题!.pdf 13 22道面试常问的...

    115个Java面试题和答案——终极列表(下)-word版本

    这份名为"115个Java面试题和答案——终极列表(下)"的文档,显然旨在为求职者提供一个全面的准备指南,帮助他们应对各种Java面试挑战。以下是文档中可能包含的一些核心知识点,以及对这些知识点的详细解释: 1. **...

    java集合类原理面试题

    大部分如`HashSet`、`ArrayList`、`HashMap`等是线程不安全的,它们在多线程环境下可能导致数据不一致。线程安全的集合类如`Vector`和`Hashtable`虽然确保线程安全,但性能较差。从Java 5开始,`java.util....

    java基础之集合面试题共4页.pdf.zip

    9. **并发集合**:Java提供了一些并发友好的集合类,如ConcurrentHashMap、CopyOnWriteArrayList和ConcurrentSkipListMap,它们在多线程环境下具有更好的性能和安全性。 10. **集合的不可变性**:Collections....

    Java面试题和答案——终极(上、下)_尚硅谷_宋红康.zip

    这份压缩包由两个PDF文件组成:115个Java面试题和答案——终极(下)_尚硅谷_宋红康.pdf以及115个Java面试题和答案——终极(上)_尚硅谷_宋红康.pdf,共涵盖了230个问题和对应的解析。这些题目涉及了Java的基础语法...

    115个Java面试题和答案——终极(下)(1).rar

    这份名为“115个Java面试题和答案——终极(下)(1).rar”的压缩包文件包含了大量Java面试的相关问题及其解答,旨在帮助求职者提升面试表现。文档中的问题涵盖了Java语言的基础知识、进阶特性以及实际开发中的常见...

    115个Java面试题和答案——终极(上)_尚硅谷_宋红康.zip ) 您可以上传小于60MB的文件

    这份"115个Java面试题和答案——终极(上)"的资料,由尚硅谷的宋红康提供,旨在帮助Java开发者准备面试,提升自己的竞争力。以下是部分重要的Java面试知识点的详细解释: 1. **Java基础** - **数据类型**:Java有...

    BAT 115个Java面试题和答案——终极(上)

    这份“BAT 115个Java面试题和答案——终极(上)”的资源提供了丰富的学习材料,旨在帮助Java开发者深入理解语言的核心概念、高级特性以及在实际开发中的应用。以下是一些关键知识点的概述: 1. **基础语法**:面试...

    java经典面试题(典藏版)

    Java编程语言作为软件开发领域的主流技术之一,其面试题涵盖了广泛的知识点,是评估开发者技能的重要途径。在准备Java面试时,了解并掌握经典题目能够帮助求职者更好地展示自己的技术水平和解决问题的能力。以下是...

    Java笔试题————精华中的精华

    "Java笔试题——精华中的精华"这个资源集锦了多种技术领域的题目,旨在帮助求职者全面准备Java相关的技术考核。这份资料涵盖了Java语言本身,以及与之紧密相关的数据库技术Oracle,Web开发JavaWeb、Html,前端技术...

    115个Java面试题和答案——终极(上)(1).rar

    这份名为“115个Java面试题和答案——终极(上)(1).rar”的压缩包文件,显然是一个宝贵的资源,它包含了大量针对Java程序员的面试问题及其解答。这份文档(115个Java面试题和答案——终极(上)(1).docx)涵盖了从...

    BAT 115个Java面试题和答案——终极(下)

    在Java面试中,掌握核心知识点和能够解决实际问题的能力至关重要,特别是对于想在BAT(百度、阿里巴巴、腾讯)这样的顶级互联网公司工作的求职者而言。以下是一些基于标题和描述所暗示的Java面试知识点的详细说明: ...

    java面试题以及技巧

    │ 上海税友软件 面试题.doc │ 公司培训文档-混淆的基本概念.doc │ 基本算法.doc │ 孙卫琴精通struts.基于MVC的.java.web设计与开发.pdf │ 学习Struts提供的和Form相关标签.txt │ 日企编码规范.doc │ 电信盈科...

    java 面试题大集合包括名大公司

    "java 面试题大集合包括名大公司"这样的资源集合,通常会涵盖从基础到高级的各种问题,旨在帮助求职者全面评估和提升自己的技能。 1. **基础概念**: - **Java语法**:如变量、数据类型、运算符、流程控制(if/...

    经典java面试题(内容很详细)

    List保证元素有序,允许重复;Set不允许重复元素,无序;Map存储键值对,键唯一。深入理解ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等常用实现类的特点和适用场景,以及`Collections`类提供的各种...

    程序面试试题汇总——C/C++/Java/软件测试

    一、C语言与C++面试题汇总 1. C语言基础:理解指针、内存管理(动态内存分配与释放)、结构体、共用体、位运算等概念。 2. 函数:函数参数传递(值传递、引用传递),递归,函数指针。 3. 链表、栈、队列、树等数据...

    大公司面试题

    而 `String` 本身不是线程安全的,但因其不可变性,在多线程环境中也不会出现问题。 #### 运行时异常与一般异常有何异同? 异常是Java中用来处理运行时错误的一种机制,分为两大类:运行时异常(RuntimeException...

    java面试题及技巧4

    │ 上海税友软件 面试题.doc │ 公司培训文档-混淆的基本概念.doc │ 基本算法.doc │ 孙卫琴精通struts.基于MVC的.java.web设计与开发.pdf │ 学习Struts提供的和Form相关标签.txt │ 日企编码规范.doc │ 电信盈科...

Global site tag (gtag.js) - Google Analytics