按序打印——wait的再理解
Posted 无赖H4
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按序打印——wait的再理解相关的知识,希望对你有一定的参考价值。
我们提供了一个类:
public class Foo {
public void first() { print(“first”); }
public void second() { print(“second”); }
public void third() { print(“third”); }
}
三个不同的线程 A、B、C 将会共用一个 Foo 实例。
一个将会调用 first() 方法
一个将会调用 second() 方法
还有一个将会调用 third() 方法
请设计修改程序,以确保 second() 方法在 first() 方法之后被执行,third() 方法在 second() 方法之后被执行。
LeetCode按序打印
思路:
通过一个静态属性保留上一次打印的数字,然后加锁判断保证按序打印
加锁
public class Demo2 {
private static int lastPrinted = 3;
static class A extends Thread {
@Override
public void run() {
while (true) {
while (true) {
synchronized (Demo2.class) {
if (lastPrinted == 3) {
break;
}
}
}
System.out.println(1);
lastPrinted = 1;
}
}
}
static class B extends Thread {
@Override
public void run() {
while (true) {
while (true) {
synchronized (Demo2.class) {
if (lastPrinted == 1) {
break;
}
}
}
System.out.println(2);
lastPrinted = 2;
}
}
}
static class C extends Thread {
@Override
public void run() {
while (true) {
while (true) {
synchronized (Demo2.class) {
if (lastPrinted == 2) {
break;
}
}
}
System.out.println(3);
lastPrinted = 3;
}
}
}
public static void main(String[] args) {
Thread a = new Demo2.A();
Thread b = new Demo2.B();
Thread c = new Demo2.C();
a.start();
b.start();
c.start();
}
}
volatile
通过volatile修饰,避免因为内存可见性出现的问题(缓存问题),
但是还是会造成cpu空转
public class Demo1 {
private static volatile int lastPrinted = 3;
static class A extends Thread {
@Override
public void run() {
while (true) {
while (lastPrinted != 3) {
}
System.out.println(1);
lastPrinted = 1;
}
}
}
static class B extends Thread {
@Override
public void run() {
while (true) {
while (lastPrinted == 1) {
}
System.out.println(2);
lastPrinted = 2;
}
}
}
static class C extends Thread {
@Override
public void run() {
while (true) {
while (lastPrinted == 2) {
}
System.out.println(3);
lastPrinted = 3;
}
}
}
public static void main(String[] args) {
Thread a = new Demo2.A();
Thread b = new Demo2.B();
Thread c = new Demo2.C();
a.start();
b.start();
c.start();
}
}
wait
package 按序打印;
import timer.Demo;
public class Demo3 {
private static volatile int lastPrinted = 3;
static class A extends Thread {
@Override
public void run() {
try {
while (true) {
while (lastPrinted != 3) {
synchronized (Demo3.class) {
if (lastPrinted != 3) {
Demo3.class.wait();
}
}
}
System.out.println(1);
lastPrinted = 1;
synchronized (Demo.class) {
Demo3.class.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class B extends Thread {
@Override
public void run() {
try {
while (true) {
while (lastPrinted != 1) {
synchronized (Demo3.class) {
if (lastPrinted != 1) {
Demo3.class.wait();
}
}
}
System.out.println(2);
lastPrinted = 2;
synchronized (Demo.class) {
Demo3.class.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class C extends Thread {
@Override
public void run() {
try {
while (true) {
while (lastPrinted != 2) {
synchronized (Demo3.class) {
if (lastPrinted != 2) {
Demo3.class.wait();
}
}
}
System.out.println(3);
lastPrinted = 3;
synchronized (Demo.class) {
Demo3.class.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread a = new Demo2.A();
Thread b = new Demo2.B();
Thread c = new Demo2.C();
a.start();
b.start();
c.start();
}
}
oj
package 按序打印;
/**
*
*/
public class Foo {
private int step = 3;
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
while (step != 3) {
synchronized (this) {
if (step != 3) {
wait();
}
}
}
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
step = 1;
synchronized (this) {
notifyAll();
}
}
public void second(Runnable printSecond) throws InterruptedException {
while (step != 1) {
synchronized (this) {
if (step != 1) {
wait();
}
}
}
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
step = 2;
synchronized (this) {
notifyAll();
}
}
public void third(Runnable printThird) throws InterruptedException {
while (step != 2) {
synchronized (this) {
if (step != 2) {
wait();
}
}
}
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
step = 3;
synchronized (this) {
notifyAll();
}
}
}
以上是关于按序打印——wait的再理解的主要内容,如果未能解决你的问题,请参考以下文章