这篇博客,继续再续多线程的点滴实现。我们还是参照此人的多线程的博客系列:
http://blog.csdn.net/column/details/wangyuetingtao.html
我们这两天的博客,相当于在此系列上继续补充。系列博客的第三集
锁机制,其中是讲到实现同步方式:同步代码块和同步方法。其实,若是确切的说,应该还有一种方式:使用JDK的锁Lock。至于同步代码块和同步方式,我们看作一种。
package com.thread;
import java.util.concurrent.locks.ReentrantLock;
/**
* 账户类
* @author liubing
*
*/
public class Account2 {
private final ReentrantLock lock=new ReentrantLock();
//账号
private String accountNo;
//余额
private int balance;
/**
* 构造函数,设置账号和余额
* @param accountNo
* @param balance
*/
public Account2(String accountNo, int balance) {
this. accountNo = accountNo;
this. balance = balance;
}
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this. accountNo = accountNo;
}
public int getBalance() {
return balance;
}
//提供一个线程安全的方法完成取钱操作
public void drawCash( int drawAccount) {
//对同步锁进行加锁
lock.lock();
try{
if( balance >= drawAccount) {
System. out.println(Thread. currentThread().getName() + " 取钱成功,取款金额:" + drawAccount);
//修改余额
balance -= drawAccount;
System. out.println( "此时余额:" + balance );
} else {
System. out.println(Thread. currentThread().getName() + " 取钱失败,余额不足!" );
}
}finally{
lock.unlock();
}
}
}
线程类与系列博客一样:直接调用方法即可。
package com.thread;
public class DrawCashThread extends Thread{
//模拟用户账户
private Account2 account;
//模拟取钱数
private int drawCash;
public DrawCashThread(String name, Account2 account, int drawCash) {
super(name);
this. account = account;
this. drawCash = drawCash;
}
public void run() {
account.drawCash(drawCash);
}
}
其中,我们为了防止手动修改余额,我们把setbalance去掉。
从JDK1.5以后,Java提供了同步锁机制。锁分为很多形式,比如只读锁,读写锁,不过我们一般都用可重入锁,ReentrantLock。
那Lock对象与同步方法或同步代码块的方式有何区别呢?
从那代码中:我们可以发现:
第一:Lock对象需要显示定义,在访问共享资源之前,首先或的lock对象。并且Lock对象,需要手动释放。一般加锁和释放不在同一片区域,一般建议在finally中释放锁。
而我们同步方式,不需要手动释放,运行完毕,即可自动释放资源。
第二:Lock对象能够做同步方式的工作,lock对象比较强大。但是同步方式,很方便。