一道面试题
最近在校招,我们的题库里面有这样一道题:3个线程,分别打印a、b、c,保证打印顺序:abc。
我觉得这道题挺有意思的,所以在这道题上面再做了一点扩展。
1.1 启动3个线程分别打印abc
public Thread createThread(final String name, final CountDownLatch countDownLatch) {
return new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(new Random().nextInt(1000)%1000);
}
catch (Exception e) {
}
countDownLatch.countDown();
System.out.println(name);
}
});
}
/**
* CountDownLatch
*/
public void test1(){
final CountDownLatch countDownLatch= new CountDownLatch(3);
createThread("A", countDownLatch).start();
createThread("B", countDownLatch).start();
createThread("C", countDownLatch).start();
try {
countDownLatch.await();
}
catch (Exception e) {
}
}
1.2 使用Semaphore 完成保证打印顺序:abc
public Thread createThread(final String name, final CountDownLatch countDownLatch, final Semaphore acquire, final Semaphore release) {
return new Thread(new Runnable() {
@Override
public void run() {
try {
acquire.acquire();
Thread.sleep(new Random().nextInt(1000)%1000);
countDownLatch.countDown();
System.out.println(name);
release.release();
}
catch (Exception e) {
}
}
});
}
/**
* Semaphore
*/
public void test2(){
final CountDownLatch countDownLatch= new CountDownLatch(3);
final Semaphore A = new Semaphore(1);
final Semaphore B = new Semaphore(0);
final Semaphore C = new Semaphore(0);
createThread("A", countDownLatch, A, B).start();
createThread("B", countDownLatch, B, C).start();
createThread("C", countDownLatch, C, A).start();
try {
countDownLatch.await();
}
catch (Exception e) {
}
}
1.3 使用AtomicInteger 完成保证打印顺序:abc
public Thread createThread(final char name, final CountDownLatch countDownLatch,final AtomicInteger single) {
return new Thread(new Runnable() {
@Override
public void run() {
try {
while (single.get()%3!=name%3){
}
Thread.sleep(2000);
System.out.println(name);
countDownLatch.countDown();
single.incrementAndGet();
}
catch (Exception e) {
}
}
});
}
/**
* while
*/
public void test4(){
final AtomicInteger single= new AtomicInteger(2);
final CountDownLatch countDownLatch= new CountDownLatch(3);
createThread('A', countDownLatch, single).start();
createThread('B', countDownLatch, single).start();
createThread('C', countDownLatch, single).start();
try {
countDownLatch.await();
}
catch (Exception e) {
}
}
1.4 使用condition 完成保证打印顺序:abc
public Thread createThread(final char name, final CountDownLatch countDownLatch,final AtomicInteger single, final Condition condition, final ReentrantLock lock) {
return new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
while (single.get()%3!=name%3){
condition.await();
}
Thread.sleep(new Random().nextInt(1000)%1000);
System.out.println(name);
countDownLatch.countDown();
single.incrementAndGet();
condition.signalAll();
}
catch (Exception e) {
}
finally {
lock.unlock();
}
}
});
}
/**
* ReentrantLock
* Condition
*/
public void test3(){
final ReentrantLock lock= new ReentrantLock();
final Condition condition= lock.newCondition();
final AtomicInteger single= new AtomicInteger(0);
final CountDownLatch countDownLatch= new CountDownLatch(3);
createThread('A', countDownLatch, single, condition, lock).start();
createThread('B', countDownLatch, single, condition, lock).start();
createThread('C', countDownLatch, single, condition, lock).start();
try {
countDownLatch.await();
}
catch (Exception e) {
}
}
1.5 使用synchronized 完成保证打印顺序:abc
public Thread createThread2(final char name, final CountDownLatch countDownLatch,final AtomicInteger single) {
return new Thread(new Runnable() {
@Override
public void run() {
try {
while (single.get()%3!=name%3){
synchronized (single){
single.wait();
}
}
Thread.sleep(new Random().nextInt(1000)%1000);
System.out.println(name);
countDownLatch.countDown();
single.incrementAndGet();
synchronized (single){
single.notifyAll();
}
}
catch (Exception e) {
}
finally {
}
}
});
}
/**
* synchronized
*/
public void test5(){
final AtomicInteger single= new AtomicInteger(2);
final CountDownLatch countDownLatch= new CountDownLatch(3);
createThread2('A', countDownLatch, single).start();
createThread2('B', countDownLatch, single).start();
createThread2('C', countDownLatch, single).start();
try {
countDownLatch.await();
}
catch (Exception e) {
}
}