锁定Java多线程无法正常工作

时间:2018-10-04 15:37:37

标签: java multithreading locking

  //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         NoLock自动柜员机: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??

还有什么应该等到完成之后呢?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

问题与重入锁的使用有关。在您的情况下,MyClass线程的每个实例将具有其自己的完成锁实例。为了使MyClass线程的2个实例同步,您应该使用共享对象。在main方法中创建完成锁实例,然后将该实例传递给两个线程

new MyClass(noLockATM, lockedATM, completionLock);

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