交替打印-Interleaving,要求两个线程交替输出
分享于 点击 6480 次 点评:184
交替打印-Interleaving,要求两个线程交替输出
目录
- 交替打印奇偶数
- 交替打印ABC
- 交替打印数字
- 总结与思考
交替打印奇偶数
题目概述
题目概述
创建两个线程,一个打印奇数,一个打印偶数。要求两个线程交替输出,顺序打印出 1 2 3 4 5 ... 100
。
解法一:synchronized + wait/notify
public class Main {
private static final Object lock = new Object();
private static int count = 1;
public static void main(String[] args) {
Thread odd = new Thread(() -> {
while (count <= 100) {
synchronized (lock) {
if ((count & 1) == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName() + ": " + count);
count++;
lock.notify();
}
}
}
}, "ODD");
Thread even = new Thread(() -> {
while (count <= 100) {
synchronized (lock) {
if ((count & 1) == 1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName() + ": " + count);
count++;
lock.notify();
}
}
}
}, "EVEN");
odd.start();
even.start();
}
}
解法二:Semaphore
import java.util.concurrent.Semaphore;
public class Main {
static int count = 1;
static Semaphore oddSemaphore = new Semaphore(1);
static Semaphore evenSemaphore = new Semaphore(0);
public static void main(String[] args) {
new Thread(() -> {
while (count <= 100) {
try {
oddSemaphore.acquire();
if (count > 100) break;
System.out.println(("ODD : " + count++));
evenSemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
while (count <= 100) {
try {
evenSemaphore.acquire();
if (count > 100) break;
System.out.println(("EVEN : " + count++));
oddSemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
交替打印ABC
题目概述
创建三个线程,分别打印 "A"、"B"、"C",要求按顺序交替输出 ABCABC...
,共打印 10 次。
解法一:synchronized + wait/notify
public class Main {
private static int state = 0;
private static final Object lock = new Object();
public static void main(String[] args) {
int loop = 10;
new Thread(() -> printLetter('A', 0, 10)).start();
new Thread(() -> printLetter('B', 1, 10)).start();
new Thread(() -> printLetter('C', 2, 10)).start();
}
private static void printLetter(char ch, int target, int loop) {
for (int i = 0; i < loop;) {
synchronized (lock) {
if (state != target) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(ch);
state = (state + 1) % 3;
lock.notifyAll();
i++;
}
}
}
}
}
解法二:ReentrantLock + Condition
import java.util.concurrent.locks.*;
public class Main {
private static int state = 0;
private static final Lock lock = new ReentrantLock();
private static final Condition A = lock.newCondition();
private static final Condition B = lock.newCondition();
private static final Condition C = lock.newCondition();
public static void main(String[] args) {
int loop = 10;
new Thread(() -> print('A', 0, A, B, loop)).start();
new Thread(() -> print('B', 1, B, C, loop)).start();
new Thread(() -> print('C', 2, C, A, loop)).start();
}
private static void print(char ch, int target, Condition curr, Condition next, int loop) {
for (int i = 0; i < loop;) {
lock.lock();
try {
while (state != target) {
curr.await();
}
System.out.println(ch);
state = (state + 1) % 3;
i++;
next.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
交替打印数字
题目概述
用3个线程打印 1~100
的整数,要求3个线程按顺序轮流打印
解法一:synchronized + wait/notify
public class Main {
private static int count = 1;
private static final Object lock = new Object();
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
int id = i;
new Thread(() -> {
while (true) {
synchronized (lock) {
if (count > 100) break;
if (count % 3 != id) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(count++);
lock.notifyAll();
}
}
}
}).start();
}
}
}
解法二:ReentrantLock + Condition
import java.util.concurrent.locks.*;
public class Main {
private static int num = 1;
private static final Lock lock = new ReentrantLock();
private static final Condition[] cons = new Condition[3];
private static int state = 0;
public static void main(String[] args) {
for (int i = 0; i < 3; i++) cons[i] = lock.newCondition();
for (int i = 0; i < 3; i++) {
int id = i;
new Thread(() -> {
while (true) {
lock.lock();
try {
if (state % 3 != id) {
cons[id].await();
} else {
if (num > 100) {
for (Condition c : cons) c.signalAll();
break;
}
System.out.println(id + " " + num);
num++;
state = (state + 1) % 3;
cons[(id + 1) % 3].signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}).start();
}
}
}
总结与思考
- 用while (true)
- 及时释放锁避免死锁
相关文章
- 暂无相关文章
用户点评