当前位置: 首页 > 知识库问答 >
问题:

锁定java多线程不工作

方飞鸣
2023-03-14
  //I have this main class

    package IntroductionLocks;

    public class Intro {

        public static void main(String[] args) {
            NoLockATM noLockATM = new NoLockATM();
            LockedATM lockedATM = new LockedATM();
            MyClass thread1 = new MyClass(noLockATM, lockedATM);
            MyClass thread2 = new MyClass(noLockATM, lockedATM);

            thread1.start();
            thread2.start();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            thread1.waitUntilDone();
            thread2.waitUntilDone();

            System.out.println("NoLock ATM: " + noLockATM.getBalance());
            System.out.println("Locked ATM: " + lockedATM.getBalance());
            int v = thread1.delta + thread2.delta + 100;
            System.out.println("Should Be: " + v);
            System.out.println("Program terminating.");
        }

    }


    //// 2nd class

    package IntroductionLocks;

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

    import CtCILibrary.AssortedMethods;

    public class MyClass extends Thread  {
        private NoLockATM noLockATM;
        private LockedATM lockedATM;
        public int delta = 0;

        private Lock completionLock;

        public MyClass(NoLockATM atm1, LockedATM atm2) {
            noLockATM = atm1;
            lockedATM = atm2;
            completionLock = new ReentrantLock();
        }

        public void run() {
    //question here
            completionLock.lock();
            int[] operations = {10,20};//AssortedMethods.randomArray(20, -50, 50);
            for (int op : operations) {
                System.out.println(Thread.currentThread().getName());
                delta += op;
                if (op < 0) {
                    int val = op * -1;
                    noLockATM.withdraw(val);
                    lockedATM.withdraw(val);
                } else {
                    noLockATM.deposit(op);
                    lockedATM.deposit(op);              
                }
            }
            completionLock.unlock();
        }

        public void waitUntilDone() {
            completionLock.lock();
            completionLock.unlock();
        }
    }


//// 3rd class LockedATM

package IntroductionLocks;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockedATM {
    private Lock lock;
    private int balance = 100;

    public LockedATM() {
        lock = new ReentrantLock();
    }

    public int withdraw(int value) {
        lock.lock();
        int temp = balance;
        try {
            Thread.sleep(100);
            temp = temp - value;
            Thread.sleep(100);
            balance = temp;
        } catch (InterruptedException e) {      }
        lock.unlock();
        return temp;
    }

    public int deposit(int value) {
        lock.lock();
        int temp = balance;
        try {
            Thread.sleep(100);
            temp = temp + value;
            Thread.sleep(100);
            balance = temp;
        } catch (InterruptedException e) {      }
        lock.unlock();
        return temp;
    } 

    public int getBalance() {
        return balance;
    }
}

我的问题是。。。为什么选择completionLock。run方法中的lock()未锁定资源。当我在系统中运行程序时。出来println(Thread.currentThread())。getName())

我得到以下输出:Thread-1 Thread-0 Thread-0 Thread-1 NoLock ATM:130 Locked ATM:160应该是:160程序终止。

    `enter code here`isnt lock supposed to lock the resource....that mean only one thread can get access to it at a time.....????? then why it is showing that first thread 1 is getting acces then thread 0 then again thread 0 and then thread1 ???

   Isnt only thread1/0 should get first completed than other??

还有什么是等到完成才应该做的呢???

共有2个答案

尉迟明贤
2023-03-14

问题在于可重入锁的使用。在您的情况下,MyClass线程的每个实例都有自己的completionLock实例。要同步MyClass线程的2个实例,应该使用共享对象。在main方法中创建completionLock实例,并将该实例传递给两个线程

new MyClass(noLockATM, lockedATM, completionLock);

public MyClass(NoLockATM atm1, LockedATM atm2, ReentrantLock completionLockArg) {
         this.noLockATM = atm1;
         this.lockedATM = atm2;
         this.completionLock = completionLockArg; 
}
徐栋
2023-03-14

每个Runnable都有自己的锁对象。这就是答案。您需要有一个共享锁。或者使用一个ATM对象作为锁

 类似资料:
  • 我正在修改一个Java服务器软件。整个应用程序是单线程的。我的一个更改需要很多时间,所以我决定异步执行,以避免冻结主线程。 问题是:这种锁在Java中的最佳实现是什么?例如,我是否应该使用亲自完成。 编辑:看看我当前实现的答案。

  • 问题内容: 我使用此类来管理与基础SQLiteDatabase的连接 它包含两个锁,一个用于读取,第二个用于写入。但是我仍然偶尔会遇到这种例外情况: 这意味着,在尝试获取getWritableDatabase中的锁定时,数据库以某种方式被锁定。 我的SQLiteOpenHelper是单例模式,并且DataSources仅使用BasicDataSource作为父类。 我可以做些什么来避免在显示的代码

  • 问题内容: 我正在努力加快某些过程的执行速度,这些过程将大量记录(大多数是几百万个)发布到Elasticsearch。在我的C#代码中,我已经使用Dataflow实现了一个多线程解决方案,如下所示: 然后我要实现的发送批量请求调用: 我的问题 ,你 是对的实用性存在的数据流管道的一部分的锁内执行额外的线程。 这个可以吗?我可以在性能,执行,缓存/内存丢失等方面看到任何潜在的问题吗? 任何见识都会很

  • 我试图理解java中的公平锁,并从中执行了一个实现 http://tutorials.jenkov.com/java-concurrency/starvation-and-fairness.html 哪个很好 代码如下所示 队列对象的代码 我了解其中的大部分,但我有两个疑问 1)在这一行代码中 这个零件是做什么用的? 它有什么作用?因为我删除了这部分代码,得到了相同的正确结果。 2) 因为我相信我

  • 问题内容: 我有一个Web应用程序,并且正在使用Oracle数据库,并且有一种基本上像这样的方法: 现在没有任何类型的同步,因此n个线程当然可以自由地访问此方法,当2个线程都进入此方法都进行检查并且当然还没有任何东西时,就会出现问题,然后它们都可以提交事务并创建一个重复的对象。 我不想在数据库中使用唯一的密钥标识符来解决此问题,因为我认为我不应该抓住它。 我也不能在提交之前进行检查,因为不仅要进行

  • 主要内容:1 什么是Java线程死锁,2 Java线程死锁的例子1 什么是Java线程死锁 Java中的死锁是多线程的一部分。当线程正在等待由另一个线程获取的对象锁而第二个线程正在等待由第一个线程获取的对象锁时,可能会发生死锁。由于两个线程都在互相等待释放锁,因此这种情况称为死锁。 2 Java线程死锁的例子 输出结果为: