【问题标题】:lock in java multithreading is not workingjava多线程中的锁不起作用
【发布时间】:2018-10-04 15:37:37
【问题描述】:
  //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;
    }
}

我的问题是……为什么 run 方法中的 completionLock.lock() 没有锁定资源。当我运行程序时,在 System.out.println(Thread.currentThread().getName())

我得到以下输出: 线程 1 线程-0 线程-0 线程 1 无锁自动柜员机:130 锁定的自动柜员机: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??

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

【问题讨论】:

    标签: java multithreading locking


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      问题在于使用可重入锁。在您的情况下,MyClass 线程的每个实例都有自己的完成锁实例。为了同步 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; 
      }
      

      【讨论】:

      • 所以因为每当调用 myclass 构造函数时,由于 completionLock = new ReentrantLock(); 会创建一个新锁......所以我从中推断出......资源的锁定取决于类的实例..在我的情况下..有2个myclass的实例,并且要同步,那么两者都应该具有相同的锁定对象????如果我错了,请纠正我..你还能指出waituntildone方法的意义吗??
      • 是的..你说得对..任何线程集都必须以同步方式工作。它必须位于所有线程都可以访问的锁对象上。另外,我认为您声明的 waitUntilDone 方法没有任何意义。它只是锁定和解锁可重入锁,对同步没有任何帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-06
      • 1970-01-01
      • 1970-01-01
      • 2013-12-28
      • 2014-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多