Flask接口签名sign原理与实例代码浅析
249
2022-12-29
java多线程实现有序输出ABC
3个线程,线程1输出A,线程2输出B,线程3输出C,让这个3个线程循环有序地输出ABCABC…
看到这个题目,感觉很有意思,问题的本质是在多线程执行环境,控制线程的执行顺序,实现的方式有非常多种,本质上需要解决java多线程环境下的线程执行的同步和利用锁机制来控制线程的执行顺序。
方式1:利用synchronized
这种方式也就是使用java内置的monitor机制,配合wait和notifyAll,代码如下:
(1)利用volatile做线程间资源的同步访问,同时作为线程调度的标志;
(2)利用notifyAll来唤醒其他等待当前的monitor资源的线程;
public class ThreadOrderWithSync {
private volatile int flag = 'A';
private final static Object LOCK = new Object();
Runnable a = () -> {
while (true) {
synchronized (LOCK) {
if (flag == 'A' ) {
System.out.println("A");
flag = 'B';
ihjsYlYP // let other thread race to get the monitor
LOCK.notifyAll();
} else {
try {
LOCK.wait();
} catcihjsYlYPh (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Runnable b = () -> {
while (true) {
synchronized (LOCK) {
if (flag == 'B' ) {
System.out.println("B");
flag = 'C';
// let other thread race to get the monitor
LOCK.notifyAll();
} else {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Runnable c = () -> {
while (true) {
synchronized (LOCK) {
if (flag == 'C' ) {
System.out.println("C");
flag = 'A';
// let other thread race to get the monitor
LOCK.notifyAll();
} else {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
public void runTest() {
Thread ta = new Thread(a);
Thread tb = new Thread(b);
Thread tc = new Thread(c);
ta.start();
tb.start();
tc.start();
}
public static void main(String[] args) {
ThreadOrderWithSync sync = new ThreadOrderWithSync();
sync.runTest();
}
}
方式2:利用并发包ReentrantLock和Condition的锁机制
上面方式1的synchronized机制,因为当前的所有线程都争用同一个monitor资源,因此只能通过notifyAll来通知其他线程来加锁,因此每次都会出现race condition,但是,通过ReentrantLock的Condition,我们可以精确控制,下一个该唤醒signal的线程是哪一个(因为我们知道执行的顺序是A->B->C的循环),相比synchronized的机制,Cohttp://ndition机制可以更精细化线程的调度设计,代码示例如下:
/**
* @author xijin.zeng created on 2018/8/31
* Thrads runing order: A->B->C
*/
public class ThreadOrderWithCondition {
private static final ReentrantLock LOCK = new ReentrantLock();
private static final Condition C_A = LOCK.newCondition();
private static final Condition C_B = LOCK.newCondition();
private static final Condition C_C = LOCK.newCondition();
/**
* init for A to run first
*/
private volatile int flag = 'A';
Runnable a = () -> {
while (true) {
LOCK.lock();
if (flag == 'A') {
System.out.println("A");
flag = 'B';
// signal B to run
C_B.signal();
} else {
try {
// block and wait signal to invoke
C_A.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
LOCK.unlock();
}
};
Runnable b = () -> {
while (true) {
LOCK.lock();
if (flag == 'B') {
System.out.println("B");
flag = 'C';
// signal C to run
C_C.signal();
} else {
try {
// block and wait signal to invoke
C_B.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
LOCK.unlock();
}
};
Runnable c = () -> {
while (true) {
LOCK.lock();
if (flag == 'C') {
System.out.println("C");
flag = 'A';
// signal A to run
C_A.signal();
} else {
try {
// block and wait signal to invoke
C_C.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
LOCK.unlock();
}
};
public void runTest() {
Thread threadA = new Thread(a);
Thread threadB = new Thread(b);
Thread threadC = new Thread(c);
threadA.start();
threadB.start();
threadC.start();
}
public static void main(String[] args) {
ThreadOrderWithCondition o = new ThreadOrderWithCondition();
o.runTest();
}
}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~