我写了一段代码,它应该使用运行在不同线程上的两种不同方法来打印“乒乓”。
共享工作代码:
package threading;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PingPong {
private static volatile int times;
private static volatile boolean ping;
private static final Lock lock = new ReentrantLock();
private static void ping() {
int i = 1;
while (i < times) {
lock.lock();
if (ping) {
System.out.print("ping ");
ping = !ping;
i += 1;
}
lock.unlock();
}
}
private static void pong() {
int i = 1;
while (i < times) {
lock.lock();
if (!ping) {
System.out.println("pong");
ping = !ping;
i += 1;
}
lock.unlock();
}
}
public static void main(String[] args) {
times = 10;
ping =true;
Thread pingThread = new Thread(PingPong::ping);
Thread pongThread = new Thread(PingPong::pong);
pingThread.start();
pongThread.start();
}
}
本例中的输出:
ping pong
ping pong
ping pong
ping pong
ping pong
ping pong
ping pong
ping pong
ping pong
如果我用for循环替换ping和pong方法中的while循环,同一个线程似乎一次又一次地锁定,不给第二个线程公平的机会进入。这种情况下的输出是不一致的,每次都出现不同的结果。while循环执行的事情是否不同,从而给第二个线程获得锁的机会?
2条答案
按热度按时间oxcyiej71#
我看不出"for"和"while"之间有什么特别的区别,但是你编写的代码,即使有"while",也不能保证你想要的行为。
从ReentrantLock documentation:
此类的构造函数接受一个可选的公平参数。当设置为true时,在争用情况下,锁优先将访问权授予等待时间最长的线程。否则,此锁不保证任何特定的访问顺序。
你应该使用一个"公平"的锁来避免一个线程挨饿。即使这样,也不能保证当一个线程拥有锁时,另一个线程会调用它自己的lock(),以确保它在unlock()执行后立即成为下一个线程。
wkftcu5l2#
您可以在每个循环之间使用延迟或使用其他方法来控制线程。