//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;
}
}
у меня вопрос ... почему завершениеLock.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??
И что ждать, пока не будет сделано ???




У каждого из ваших runnables есть собственный объект блокировки. Вот и ответ.
У вас должна быть общая блокировка. Или используйте один из ваших объектов ATM в качестве замка
Проблема заключается в использовании блокировки повторного входа. В вашем случае каждый экземпляр потока MyClass будет иметь собственный экземпляр завершенияLock. Чтобы вы могли синхронизировать 2 экземпляра потока MyClass, вы должны использовать общий объект. Создайте экземпляр завершенияLock в основном методе и передайте его обоим потокам.
new MyClass(noLockATM, lockedATM, completionLock);
public MyClass(NoLockATM atm1, LockedATM atm2, ReentrantLock completionLockArg) {
this.noLockATM = atm1;
this.lockedATM = atm2;
this.completionLock = completionLockArg;
}
Да ... вы правильно поняли ... для того, чтобы любой набор потоков работал синхронно., Он должен быть на объекте блокировки, который доступен для всех потоков. Кроме того, я не вижу значения объявленного вами метода waitUntilDone. Он просто блокирует и разблокирует повторный вход и никоим образом не помогает для синхронизации.
поэтому, потому что всякий раз, когда вызывается конструктор myclass, создается новая блокировка из-за завершенияLock = new ReentrantLock (); ... Итак, что я делаю из этого, это .... блокировка ресурса зависит от экземпляра класса .... здесь в моем случае .. есть 2 экземпляра myclass, и чтобы оба синхронизировались, оба должны иметь один и тот же объект блокировки ???? поправьте меня, если я ошибаюсь .. также можете указать значение метода waituntildone ??