本文主要列举常见并发编程笔试题,以便能够熟练使用常见并发编程
题目一:三个线程循环打印abc,共打印100次
解法1:lock.condition和countdownlatch
思路一个volatile变量num记录打印次数,lock对象new3个condition对象c1 c2 c3,每次打印时一个对象等待,打印后另一个对象唤醒,相互循环
代码如下:
java
private static volatile int num = 100;
@Test
public void testCase() throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
Condition c1 = lock.newCondition();
Condition c2 = lock.newCondition();
Condition c3 = lock.newCondition();
CountDownLatch countDownLatch = new CountDownLatch(3);
new Thread(new PrintTask(lock, c1, c2, 'a', countDownLatch)).start();
new Thread(new PrintTask(lock, c2, c3, 'b', countDownLatch)).start();
new Thread(new PrintTask(lock, c3, c1, 'c', countDownLatch)).start();
countDownLatch.await();
lock.lock();
try {
c1.signalAll();
} finally {
lock.unlock();
}
while (num > 0) {
LockSupport.parkNanos(1000L);
}
}
private static class PrintTask implements Runnable {
private Condition c1;
private Condition c2;
private Lock lock;
private char ch;
private CountDownLatch countDownLatch;
public PrintTask(Lock lock, Condition c1, Condition c2, char ch, CountDownLatch countDownLatch) {
this.c1 = c1;
this.c2 = c2;
this.ch = ch;
this.lock = lock;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
countDownLatch.countDown();
while (num > 0) {
lock.lock();
try {
c1.await();
if (num > 0) {
System.out.println(ch);
num--;
}
c2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
解法2:使用三个信号量semaphore来解
思路同解法1
java
private static volatile int num = 100;
@Test
public void testCase() {
Semaphore semaphoreA = new Semaphore(1);
Semaphore semaphoreB = new Semaphore(0);
Semaphore semaphoreC = new Semaphore(0);
Thread threadA = new Thread(new PrintTask('a', semaphoreA, semaphoreB));
Thread threadB = new Thread(new PrintTask('b', semaphoreB, semaphoreC));
Thread threadC = new Thread(new PrintTask('c', semaphoreC, semaphoreA));
threadA.start();
threadB.start();
threadC.start();
}
private static class PrintTask implements Runnable {
private char character;
private Semaphore currentSemaphore;
private Semaphore nextSemaphore;
public PrintTask(char character, Semaphore currentSemaphore, Semaphore nextSemaphore) {
this.character = character;
this.currentSemaphore = currentSemaphore;
this.nextSemaphore = nextSemaphore;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
currentSemaphore.acquire();
if (num > 0) {
System.out.println(character);
num--;
}
nextSemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
解法3:使用Object,条件性判断是否需要wait
代码如下:
java
private static final Object lock = new Object();
private static volatile int count = 0;
@Test
public void testCase() {
Thread threadA = new Thread(new PrintTask('A', 0));
Thread threadB = new Thread(new PrintTask('B', 1));
Thread threadC = new Thread(new PrintTask('C', 2));
threadA.start();
threadB.start();
threadC.start();
}
private static class PrintTask implements Runnable {
private char character;
private int targetCount;
public PrintTask(char character, int targetCount) {
this.character = character;
this.targetCount = targetCount;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
try {
while (count % 3 != targetCount) {
lock.wait();
}
System.out.println(character);
count++;
lock.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}