Java:多线程安全问题:使用Thread extends和Lock

标签 java multithreading concurrency reentrantlock

当我使用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/

相关文章:

Java GAE::错误:“权限被拒绝:不允许发出套接字连接:权限被拒绝..

java - 如何轻松监控 Eden 和 Survivor Spaces 的使用情况

java - 为 JavaFX Scenic View 设置的元素

C# : Invoke a method with [Type]. InvokeMember() 在单独的线程中

c++ - 是否可以为并行区域中的共享二维数组创建选择元素的线程本地拷贝? (共享、私有(private)、屏障 : OPenMP)

java - 如何使用 Java 模拟阻塞函数

java - 无法使用firefox的Rest Client进行post调用

swift - 当保存在后台异步完成时,我应该如何保证嵌套上下文中不同线程的获取结果是最新的?

python - Python 和 Qt 中的并发编程

c# - 我可以避免对很少更改的变量使用锁吗?