スレッド同期の必要性
3663 ワード
1、口座類
2、引き出しスレッド(同じ口座を持つ)
3、テストクラス
実行結果:
夫は金を引き出すつもりだ.妻は金を引き出すつもりだ.妻は引き出しを済ませた.妻は金を引き出すつもりだ.夫は引き出しを済ませた.夫は金を引き出すつもりだ.妻は引き出しを済ませた.妻は金を引き出すつもりだ.夫は引き出しを済ませた.夫は金を引き出すつもりだ.妻は引き出しを済ませた.夫は引き出しを済ませた.妻は金を引き出すつもりだ.夫は金を引き出すつもりだ.夫は引き出しを済ませた.口座が貸越した!妻は引き出しを済ませた.口座が貸越した!残高は妻の引き出しを支払うのに十分ではありません.残高は-100口座の貸越です.残高は夫の引き出しを支払うのに十分ではありません.残高は-100口座の貸越です.4、同期方法
実行結果:
夫は金を引き出すつもりだ.夫は引き出しを済ませた.妻は金を引き出すつもりだ.妻は引き出しを済ませた.妻は金を引き出すつもりだ.妻は引き出しを済ませた.妻は金を引き出すつもりだ.妻は引き出しを済ませた.夫は金を引き出すつもりだ.夫は引き出しを済ませた.残高は夫の引き出しを支払うのに十分ではなく、残高は0残高で夫の引き出しを支払うのに十分ではなく、残高は0残高で夫の引き出しを支払うのに十分ではなく、残高は0残高で妻の引き出しを支払うのに十分ではなく、残高は0残高で妻の引き出しを支払うのに十分ではなく、残高は0
5、同期コードブロック(同期方法より強い)
package com.ljb.app.synchronize;
/**
* ( )
* @author LJB
* @version 2015 3 10
*/
public class Account {
//
private int balance = 500;
//
public int getBalance() {
return balance;
}
// ( < 0, >)
public void withdraw (int amount) {
balance = balance - amount;
}
}
2、引き出しスレッド(同じ口座を持つ)
package com.ljb.app.synchronize;
/**
* ( )
* @author LJB
* @version 2015 3 10
*/
public class WithdrawThread implements Runnable{
/*
*
*/
private Account account = new Account();
/*
* 、 (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run () {
for (int i = 0 ; i < 5 ; i++) {
//
makeWithdraw(100);
//
if (account.getBalance() < 0) {
System.out.println(" !");
}
}
}
/*
* ( )
*/
private void makeWithdraw (int amount) {
if (account.getBalance() >= amount) {
System.out.println(Thread.currentThread().getName() + " 。");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 0.5
account.withdraw(amount);
System.out.println(Thread.currentThread().getName() + " 。");
} else {
System.out.println(" "
+ Thread.currentThread().getName()
+ " , " + account.getBalance());
}
}
}
3、テストクラス
package com.ljb.app.synchronize;
/**
* 2
* @author LJB
* @version 2015 3 10
*/
public class TestWithdraw {
/**
* @param args
*/
public static void main(String[] args) {
// Runnable
WithdrawThread withdraw = new WithdrawThread();
// 2
Thread husband = new Thread(withdraw);
Thread wife = new Thread(withdraw);
husband.setName(" ");
wife.setName(" ");
husband.start();
wife.start();
}
}
実行結果:
夫は金を引き出すつもりだ.妻は金を引き出すつもりだ.妻は引き出しを済ませた.妻は金を引き出すつもりだ.夫は引き出しを済ませた.夫は金を引き出すつもりだ.妻は引き出しを済ませた.妻は金を引き出すつもりだ.夫は引き出しを済ませた.夫は金を引き出すつもりだ.妻は引き出しを済ませた.夫は引き出しを済ませた.妻は金を引き出すつもりだ.夫は金を引き出すつもりだ.夫は引き出しを済ませた.口座が貸越した!妻は引き出しを済ませた.口座が貸越した!残高は妻の引き出しを支払うのに十分ではありません.残高は-100口座の貸越です.残高は夫の引き出しを支払うのに十分ではありません.残高は-100口座の貸越です.4、同期方法
/*
* ( )
*/
private synchronized void makeWithdraw (int amount) {
if (account.getBalance() >= amount) {
System.out.println(Thread.currentThread().getName() + " 。");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 0.5
account.withdraw(amount);
System.out.println(Thread.currentThread().getName() + " 。");
} else {
System.out.println(" "
+ Thread.currentThread().getName()
+ " , " + account.getBalance());
}
}
実行結果:
夫は金を引き出すつもりだ.夫は引き出しを済ませた.妻は金を引き出すつもりだ.妻は引き出しを済ませた.妻は金を引き出すつもりだ.妻は引き出しを済ませた.妻は金を引き出すつもりだ.妻は引き出しを済ませた.夫は金を引き出すつもりだ.夫は引き出しを済ませた.残高は夫の引き出しを支払うのに十分ではなく、残高は0残高で夫の引き出しを支払うのに十分ではなく、残高は0残高で夫の引き出しを支払うのに十分ではなく、残高は0残高で妻の引き出しを支払うのに十分ではなく、残高は0残高で妻の引き出しを支払うのに十分ではなく、残高は0
5、同期コードブロック(同期方法より強い)
/*
* ( )
*/
private void makeWithdraw (int amount) {
synchronized (account) {
if (account.getBalance() >= amount) {
System.out.println(Thread.currentThread().getName() + " 。");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 0.5
account.withdraw(amount);
System.out.println(Thread.currentThread().getName() + " 。");
} else {
System.out.println(" "
+ Thread.currentThread().getName()
+ " , " + account.getBalance());
}
}
}