1、运行结果不惟一,取决于线程调度
2、线程执行被打断时出现错误
3、线程互斥和临界区管理
1)操作系统对共享一个变量的若干线程进入各自临界区有以下3个调度原则:
2)一次至多一个线程能够在它的临界区内。
3)不能让一个线程无限地留在它的临界区内。
4)不能强迫一个线程无限地等待进入它的临界区。特别地,进入临界区的任一线程不能妨碍正等待进入的其他线程的进展。
4、同步语句 synchronized (对象)
同步方法 synchronized 方法声明 方法声明synchronized(this){ 方法体 }
5、银行账户的存款取款线程
Account.c
package p25;
public class Account {
private String name;//储户姓名
private double balance;//账户余额
public Account(String name) {
this.name = name;
this.balance = 0;
}
//查询余额
public double balance() {
return this.balance;
}
public String getName() {
return this.name;
}
//存款操作
public void put(double value) {
if (value > 0) {
this.balance += value;
}
}
//取款操作
public double get(double value) {
if (value > 0) {
if (value < this.balance) {//够取
this.balance -= value;
} else {
value = this.balance;
this.balance = 0;
}
return value;
}
return 0;
}
}
class Save extends Thread {
private Account account;
private double value;
public Save(Account account, double value) {
this.account = account;
this.value = value;
}
public void run() {
synchronized (account) {//声明临界区,锁定当前account对象
double howmuch = this.account.balance();//查看账户余额
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.account.put(this.value);
double howmuch2 = this.account.balance();//查看账户余额
System.out.println(this.account.getName() + "账户: 现有" + howmuch
+ ",存入" + this.value + ",余额为" + howmuch2);
}
}
}
class Fetch extends Thread {
private Account account;
private double value;
public Fetch(Account account, double value) {
this.account = account;
this.value = value;
}
public void run() {
synchronized (account) {
double howmuch = this.account.balance();
try {
sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
double v = this.account.get(this.value);
double howmuch2 = this.account.balance();
System.out.println(this.account.getName() + "账户: 现有" + howmuch
+ ",取出" + v + ",余额为" + howmuch2);
}
}
}
class Func extends Thread {
private Account account;
private double value;
public Func(Account account, double value) {
this.account = account;
this.value = value;
}
public void run() {
fun();
}
synchronized void fun(){
double howmuch = this.account.balance();
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.account.put(this.value);
double v = this.account.get(this.value);
double howmuch2 = this.account.balance();
System.out.println(this.account.getName() + "账户: 现有" + howmuch + ",取出"
+ v + ",余额为" + howmuch2);
}
}
Bank.c
package p25;
public class Bank {
public static void main(String[] args) {
Account wang = new Account("wang");
(new Save(wang,100)).start();
(new Save(wang,200)).start();
(new Fetch(wang,100)).start();
Account li=new Account("li");
(new Save(li,300)).start();
Account xu=new Account("xu");
(new Func(xu,100000)).start();
}
}
正确结果:
错误结果: