当我使用Thread类和Lock解决线程安全问题时,出现0票!
代码:
package ThreadTest;
import java.util.concurrent.locks.ReentrantLock;
class ThreadOne extends Thread{
private static int ticket = 100;
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true){
try {
lock.lock();
if(ticket > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"selling ticket: "+ticket);
ticket--;
}else{
break;
}
} finally {
lock.unlock();
}
}
}
}
public class ThreadMethod {
public static void main(String[] args) {
ThreadOne t1 = new ThreadOne();
ThreadOne t2 = new ThreadOne();
t1.setName("Window 1:");
t2.setName("Window 2:");
t1.start();
t2.start();
}
}
结果包含: 窗口2:售票:3 窗口1:售票:2 窗口2:售票:1 窗口1:售票:0
0票!
最佳答案
第一个问题是每个 ThreadOne
实例都有两个独立锁,因此您实际上并没有锁定任何东西。线程之间甚至没有尝试获取锁的竞争,因为它们都有自己的锁。如果您将 ReentrantLock
static
设置为静态,则很容易修复。
如果您确实将其设置为静态
,您会注意到只有一个“窗口”会继续获取票证。这与 ReentrantLock
内部工作方式以及您使用 while(true){...}
的事实有关。这也很容易修复。要么:
将锁更改为公平:
private static ReentrantLock LOCK = new ReentrantLock(true);
或者在finally block 之后 hibernate 一段时间,让其他线程有机会运行。
像这样:
.....
} finally {
LOCK.unlock();
}
try {
Thread.sleep(10);
}
catch (InterruptedException e) {
e.printStackTrace();
}
关于Java:多线程安全问题:使用Thread extends和Lock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65912154/