大概的问题是这样的:
有A,B,C三个线程, A线程输出A, B线程输出B, C线程输出C
要求, 同时启动三个线程, 按顺序输出ABC, 循环10次
这是一个多线程协同的问题, 本身多线程是没有执行顺序的, 顺序不一定, Java在concurrent里面提供了多线程同步的支持
使用ReentrantLock来解决, 还有个state整数用来判断轮到谁执行了
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ABC {
private static Lock lock = new ReentrantLock();//通过JDK5中的锁来保证线程的访问的互斥
private static int state = 0;
static class ThreadA extends Thread {
@Override
public void run() {
for (int i = 0; i < 10;) {
lock.lock();
if (state % 3 == 0) {
System.out.print("A");
state++;
i++;
}
lock.unlock();
}
}
}
static class ThreadB extends Thread {
@Override
public void run() {
for (int i = 0; i < 10;) {
lock.lock();
if (state % 3 == 1) {
System.out.print("B");
state++;
i++;
}
lock.unlock();
}
}
}
static class ThreadC extends Thread {
@Override
public void run() {
for (int i = 0; i < 10;) {
lock.lock();
if (state % 3 == 2) {
System.out.print("C");
state++;
i++;
}
lock.unlock();
}
}
}
public static void main(String[] args) {
new ThreadA().start();
new ThreadB().start();
new ThreadC().start();
}
}
使用lock来保证只有一个线程在输出操作, 要保证了state不会被两个线程同时修改, 思路简单
还可以使用condition, condition的效率可能会更高一些, await会释放lock锁, condition的await和signal与object的wait和notify方法作用类似
package moreThread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*/
public class ABC2 {
private static Lock lock = new ReentrantLock();
private static int count = 0;
private static Condition A = lock.newCondition();
private static Condition B = lock.newCondition();
private static Condition C = lock.newCondition();
static class ThreadA extends Thread {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
while (count % 3 != 0) {
A.await(); // 会释放lock锁
System.out.print("A");
count++;
B.signal(); // 唤醒相应线程
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
static class ThreadB extends Thread {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
while (count % 3 != 0) {
B.await(); // 会释放lock锁
System.out.print("B");
count++;
C.signal(); // 唤醒相应线程
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
static class ThreadC extends Thread {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
while (count % 3 != 0) {
C.await(); // 会释放lock锁
System.out.print("C");
count++;
A.signal(); // 唤醒相应线程
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
new ThreadA().start();
new ThreadB().start();
ThreadC threadC = new ThreadC();
threadC.start();
threadC.join();
System.out.println(count);
}
}
使用信号量也可以, 这个思路最简单, 整个代码也比较简洁
import java.util.concurrent.Semaphore;
public class ABC3 {
private static Semaphore A = new Semaphore(1);
private static Semaphore B = new Semaphore(1);
private static Semaphore C = new Semaphore(1);
static class ThreadA extends Thread {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
A.acquire();
System.out.print("A");
B.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class ThreadB extends Thread {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
B.acquire();
System.out.print("B");
C.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class ThreadC extends Thread {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
C.acquire();
System.out.println("C");
A.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
B.acquire(); C.acquire(); // 开始只有A可以获取, BC都不可以获取, 保证了A最先执行
new ThreadA().start();
new ThreadB().start();
new ThreadC().start();
}
}
注意:
lock是需要lock所有者去释放的, 即谁lock, 谁释放, 不可以跨线程, 会报java.lang.IllegalMonitorStateException;
semaphore是没有所有者的说法, 可以跨线程释放和获取.
本文介绍了一种使用Java实现多线程同步的方法,确保三个线程按ABC顺序循环输出10次。通过ReentrantLock和Condition实现了线程间的同步,利用Semaphore简化了同步逻辑。
1145

被折叠的 条评论
为什么被折叠?



