方案一:循环栅栏锁 先上代码吧:
public static void pringInt() {
CyclicBarrier cyclicBarrier1 = new CyclicBarrier(2);
CyclicBarrier cyclicBarrier2 = new CyclicBarrier(2);
CyclicBarrier cyclicBarrier3 = new CyclicBarrier(3);
AtomicInteger integer = new AtomicInteger(0);
Thread a = new Thread(new Runnable() {
@Override
public void run() {
while (integer.get() < 100) {
try {
LogUtils.getInstance().d(TAG,"Thread a pringInt="+integer.incrementAndGet());
cyclicBarrier1.await();
cyclicBarrier3.await();
} catch (Exception e) {
}
}
}
});
a.start();
Thread b = new Thread(new Runnable() {
@Override
public void run() {
while (integer.get() < 100) {
try {
cyclicBarrier1.await();
LogUtils.getInstance().d(TAG,"Thread b pringInt="+integer.incrementAndGet());
cyclicBarrier2.await();
cyclicBarrier3.await();
} catch (Exception e) {
}
}
}
});
b.start();
Thread c = new Thread(new Runnable() {
@Override
public void run() {
while (integer.get() < 100) {
try {
cyclicBarrier2.await();
LogUtils.getInstance().d(TAG,"Thread c pringInt="+integer.incrementAndGet());
cyclicBarrier3.await();
} catch (Exception e) {
}
}
}
});
c.start();
}
使用CyclicBarrier栅栏屏障从而保证线程的顺序以及可重复使用的特性达到一个循环的线程
看一下结果:
方案二:自旋锁
private void test() {
AtomicInteger integer = new AtomicInteger(0);
SpinLock spinLock = new SpinLock();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while (integer.get() < 100) {
spinLock.lock(0);
int current = integer.incrementAndGet();
if (current < 101) {
LogUtils.dns(TAG, "current=" + current + ";name=" + Thread.currentThread().getName());
}
spinLock.unLock(current);//1
}
}
}, "a");
thread1.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
while (integer.get() < 100) {
spinLock.lock(1);
int current = integer.incrementAndGet();
if (current<101){
LogUtils.dns(TAG, "current=" + current + ";name=" + Thread.currentThread().getName());
}
spinLock.unLock(current);//2
}
}
}, "b");
thread2.start();
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
while (integer.get() < 100) {
spinLock.lock(2);
int current = integer.incrementAndGet();
if (current < 101) {
LogUtils.dns(TAG, "current=" + current + ";name=" + Thread.currentThread().getName());
}
spinLock.unLock(current);//0
}
}
}, "c");
thread3.start();
}
public static class SpinLock {
private final AtomicInteger owner = new AtomicInteger(0);
public void lock(int current) {
int c = current % 3;
while (!owner.compareAndSet(c, c)) ;
}
public boolean unLock(int current) {
int c = current % 3;
if (current > 0)return owner.compareAndSet((current - 1) % 3, c);
else return false;
}
}