//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??
还有什么应该等到完成之后呢?
答案 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;
}