【发布时间】:2018-08-12 14:50:12
【问题描述】:
我目前正在学习 Java 中的线程同步,并选择自己做一些测试。该程序包含几个线程,它们访问一个方法以将 1 添加到共享 int 并打印哪个线程刚刚使用了该方法以及 x 的新值是什么。目标是让线程从 0 增加到 10 并以正确的顺序打印,如下所示:
public int addNumbers() {
x++;
if (x >= 10) {
running = false;
}
return x;
}
线程:
private class RunThread extends Thread {
public void run() {
while (running) {
System.out.println(addNumbers());
}
}
}
为了创建 Mutex,我使用了 ReentrantLock,但我有一些问题:
为什么这样保证互斥并使线程以正确的顺序打印数字...:
lock.lock();
System.out.println(addNumbers());
lock.unlock();
...虽然这不是?:
public int addNumbers() {
lock.lock();
try {
x++;
if (x >= 10) {
running = false;
}
return x;
} finally {
lock.unlock();
}
}
看起来它对我做了同样的事情。以及为什么我在方法中添加一个 Thread.sleep 时它突然起作用了?:
public int addNumbers() {
lock.lock();
try {
x++;
if (x >= 10) {
running = false;
}
return x;
} finally {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
}
我试图在网上阅读它,但它对我来说没有任何意义。 请帮助和善意,我才刚刚开始学习多线程。
预期的“正确”结果(正常计数):
1
2
3
4
5
6
7
8
9
10
11
错误的结果:
2
3
1
4
5
7
6
9
8
10
完整代码:
public class LockTest {
int x = 0;
boolean running = true;
private final Lock lock = new ReentrantLock();
public static void main(String[] args) {
LockTest t1 = new LockTest();
}
public LockTest() {
init();
}
public int addNumbers() {
x++;
if (x >= 10) {
running = false;
}
return x;
}
private void init() {
Thread t1 = new RunThread();
Thread t2 = new RunThread();
Thread t3 = new RunThread();
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
private class RunThread extends Thread {
public void run() {
while (running) {
lock.lock();
System.out.println(this.getName() + ": " + addNumbers());
lock.unlock();
}
}
}
}
【问题讨论】:
-
作为一般规则,如果添加
sleep“修复”这样的事情,那么您的发生之前的关系没有完全指定。 -
定义什么是“正确的顺序”。你预计会发生什么,为什么?相反,究竟会发生什么?在所有情况下,我的期望都是未定的订单。
标签: java multithreading locking mutex