我正在研究MultiThreading
个概念。我遇到了ReentrantLock
。它有方法lock
和trylock
。当我进一步研究它们时,我知道它们可以用来代替synchronized
关键字块或方法。所以我再次尝试了Kathie Sierra书中给出的AccountDanger
的经典例子。我观察到lock
方法允许转向其他线程。但是trylock
布尔方法不允许转向其他线程。以下示例:
使用lock
方法
package p1;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class AccountDanger implements Runnable {
private Account account = new Account();
private int amt = 10;
Lock lock = new ReentrantLock();
Object obj = new Object();
public void run(){
for(int i=0;i<10;i++){
lock.lock();
try{
if(account.getBalance()>=amt){
System.out.println(Thread.currentThread().getName()+" is going to withdraw..");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.withdraw(amt);
System.out.println(Thread.currentThread().getName()+" has withdrawn. Balance left is : "+account.getBalance());
}
else{
System.out.println("not enough balance for "+Thread.currentThread().getName());
}
}finally{
lock.unlock();
}
}
if(account.getBalance()<0){
System.out.println("account is over withdrawn!!!");
}
}
public static void main(String[] args) throws InterruptedException{
AccountDanger ad = new AccountDanger();
Thread t1 = new Thread(ad,"Mark");
Thread t2 = new Thread(ad,"Phew");
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("final balance left is : "+ad.account.getBalance());
}
}
上面的代码使用lock
方法,允许Mark
和Phew
个线程轮流。
使用trylock
方法
package p1;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class AccountDanger implements Runnable {
private Account account = new Account();
private int amt = 10;
Lock lock = new ReentrantLock();
Object obj = new Object();
public void run(){
for(int i=0;i<10;i++){
try{
if(lock.tryLock()){
if(account.getBalance()>=amt){
System.out.println(Thread.currentThread().getName()+" is going to withdraw..");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.withdraw(amt);
System.out.println(Thread.currentThread().getName()+" has withdrawn. Balance left is : "+account.getBalance());
}
else{
System.out.println("not enough balance for "+Thread.currentThread().getName());
}
}
}
finally {
if(lock.tryLock()){
lock.unlock();
}
}
if(account.getBalance()<0){
System.out.println("account is over withdrawn!!!");
}
}
}
public static void main(String[] args) throws InterruptedException{
AccountDanger ad = new AccountDanger();
Thread t1 = new Thread(ad,"Mark");
Thread t2 = new Thread(ad,"Phew");
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("final balance left is : "+ad.account.getBalance());
}
}
上面的代码即使在调用Phew
方法时也不允许Thread.sleep()
线程轮流。
帐户类
package p1;
public class Account{
private int balance = 100;
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
public void withdraw(int amount){
this.balance = this.balance - amount;
}
}
但是,毫无疑问,这两种方法都可以防止平衡变得消极。但是我不明白为什么trylock
对这个过程如此认真,以至于即使在Thread.sleep
内部调用它也不允许其他线程进入执行之间。即使我在lock.unlock
的catch块之后的finally
块中使用Thread.sleep
语句,也只有mark
线程正在执行。
答案 0 :(得分:1)
你的基本误解是trylock
没有获得锁定,它确实存在;正如我在评论中所述,trylock
等同于lock
,但如果无法获取锁定则不会阻止。
您的案例中发生了什么:
run
方法并终止了Phew线程。