利用AtomicInteger的cas实现一把自定义的锁,要注意解锁的线程一定是那个加锁的线程,否则会出现别的线程把锁释放掉
先定义一个lock异常类
public class LockException extends Exception{
public LockException(String message) {
super(message);
}
}
自定义锁
public class CompareAndSetLock {
private final AtomicInteger value = new AtomicInteger(0);
private Thread currentThread;
public void tryLock() throws LockException{
final boolean succ = value.compareAndSet(0, 1);
if (!succ) {
throw new LockException("get the lock failed.");
}else {
currentThread = Thread.currentThread();
}
}
// unlock方法 可以自己想一下
}
public class CompareAndSetLockTest {
private static final CompareAndSetLock COMPARE_AND_SET_LOCK = new CompareAndSetLock();
public static void main(String[] args) {
long start = System.currentTimeMillis();
List<Thread> workers = new ArrayList<>();
Arrays.asList("M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8").stream()
.map(CompareAndSetLockTest::createThread)
.forEach(
t -> {
t.start();
workers.add(t);
});
workers.forEach(
t -> {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("消耗时间为");
System.out.println(System.currentTimeMillis() - start);
}
private static Thread createThread(String name) {
return new Thread(
() -> {
try {
COMPARE_AND_SET_LOCK.tryLock();
System.out.println(Thread.currentThread().getName() + " do something....");
Thread.sleep(10000);
} catch (LockException | InterruptedException e) {
e.printStackTrace();
} finally {
COMPARE_AND_SET_LOCK.unLock();
}
},
name);
}
private static Thread createThread1(String name) {
return new Thread(
() -> {
synchronized (CompareAndSetLockTest.class) {
System.out.println(Thread.currentThread().getName() + " do something....");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},
name);
}
public static void doSomething1() throws LockException, InterruptedException {
synchronized (CompareAndSetLockTest.class) {
System.out.println(Thread.currentThread().getName() + "do something....");
Thread.sleep(10000);
}
}
}
我们分别调用createThread和createThread1方法看看区别
createThread结果:
M1 do something....
com.concurrency.thread.atomic.LockException: get the lock failed.
at com.concurrency.thread.atomic.CompareAndSetLock.tryLock(CompareAndSetLock.java:17)
at com.concurrency.thread.atomic.integer.CompareAndSetLockTest.lambda$createThread$2(CompareAndSetLockTest.java:47)
at java.lang.Thread.run(Thread.java:748)
com.concurrency.thread.atomic.LockException: get the lock failed.
at com.concurrency.thread.atomic.CompareAndSetLock.tryLock(CompareAndSetLock.java:17)
at com.concurrency.thread.atomic.integer.CompareAndSetLockTest.lambda$createThread$2(CompareAndSetLockTest.java:47)
at java.lang.Thread.run(Thread.java:748)
com.concurrency.thread.atomic.LockException: get the lock failed.
at com.concurrency.thread.atomic.CompareAndSetLock.tryLock(CompareAndSetLock.java:17)
at com.concurrency.thread.atomic.integer.CompareAndSetLockTest.lambda$createThread$2(CompareAndSetLockTest.java:47)
at java.lang.Thread.run(Thread.java:748)
com.concurrency.thread.atomic.LockException: get the lock failed.
at com.concurrency.thread.atomic.CompareAndSetLock.tryLock(CompareAndSetLock.java:17)
at com.concurrency.thread.atomic.integer.CompareAndSetLockTest.lambda$createThread$2(CompareAndSetLockTest.java:47)
at java.lang.Thread.run(Thread.java:748)
com.concurrency.thread.atomic.LockException: get the lock failed.
at com.concurrency.thread.atomic.CompareAndSetLock.tryLock(CompareAndSetLock.java:17)
at com.concurrency.thread.atomic.integer.CompareAndSetLockTest.lambda$createThread$2(CompareAndSetLockTest.java:47)
at java.lang.Thread.run(Thread.java:748)
com.concurrency.thread.atomic.LockException: get the lock failed.
at com.concurrency.thread.atomic.CompareAndSetLock.tryLock(CompareAndSetLock.java:17)
at com.concurrency.thread.atomic.integer.CompareAndSetLockTest.lambda$createThread$2(CompareAndSetLockTest.java:47)
at java.lang.Thread.run(Thread.java:748)
com.concurrency.thread.atomic.LockException: get the lock failed.
at com.concurrency.thread.atomic.CompareAndSetLock.tryLock(CompareAndSetLock.java:17)
at com.concurrency.thread.atomic.integer.CompareAndSetLockTest.lambda$createThread$2(CompareAndSetLockTest.java:47)
at java.lang.Thread.run(Thread.java:748)
消耗时间为
10061
Process finished with exit code 0
createThread1结果:
M1 do something....
M8 do something....
M7 do something....
M6 do something....
M5 do something....
M4 do something....
M3 do something....
M2 do something....
消耗时间为
80078
Process finished with exit code 0