这是有一次去面试被问到的,当时只知道用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不能再添加,在等待中...
...