Java多线程中访问同一资源时容易引发资源竞争,而线程互斥是解决线程间资源竞争的手段。
线程互斥:若干个线程若要使用同一共享资源,任何时刻最多允许一个线程使用,其他要使用该资源的线程必须要等待,直到占有资源的线程释放资源。
Java利用synchronized实现资源互斥
synchronized有两种用法:
1.同步方法:
语法格式如下:
public synchronized void func(){
//Code
}
2.同步块
语法格式如下:
synchronized(syncObject){
//Code
}
一个多线程解决资源竞争的典型案例:
class Account{
private String name;
private double balance;
public Account() {
super();
// TODO Auto-generated constructor stub
}
public Account(String name, double balance) {
super();
this.name = name;
this.balance = 0;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public void put(double value){
if(value>0){
this.balance+=value;
}
}
public double get(double value){
if(value<0){
return 0;
}
else if(value<=this.balance){
this.balance-=value;
}
else{
value = this.balance;
this.balance=0;
}
return value;
}
}
class LockFetchThread extends Thread{
private Account account;
private double value;
public LockFetchThread(Account account, double value) {
super();
this.account = account;
this.value = value;
}
@Override
public void run(){
synchronized(this.account){
double howmatch = this.account.getBalance();
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
System.out.println(this.account.getName()+"账户:现有"+howmatch+",取走"+this.account.get(this.value)+",余额"+this.account.getBalance());
}
}
}
public class LockSaveThread extends Thread{
private Account account;
private double value;
public LockSaveThread(Account account, double value) {
super();
this.account = account;
this.value = value;
}
@Override
public void run(){
synchronized(this.account){
double howmatch = this.account.getBalance();
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
this.account.put(this.value);
System.out.println(this.account.getName()+"账户:现有"+howmatch+",存入"+this.value+",余额"+this.account.getBalance());
}
}
public static void main(String[] args){
Account wang = new Account("wang",0);
(new LockSaveThread(wang, 100)).start();
(new LockSaveThread(wang, 200)).start();
(new LockSaveThread(wang, 300)).start();
(new LockFetchThread(wang, 300)).start();
}
}
输出:
wang账户:现有0.0,存入100.0,余额100.0
wang账户:现有100.0,取走100.0,余额0.0
wang账户:现有0.0,存入300.0,余额300.0
wang账户:现有300.0,存入200.0,余额500.0