关于多线程并发环境下,数据的安全问题
什么时候数据在多线程并发的环境下会存在安全问题
a.多线程并发
b.有共享数据
c.共享的数据有修改的行为
怎么解决线程安全问题
线程排队执行(不并发)==线程同步机制
模拟两个线程对同一份账户取款
1.不使用线程同步机制
public class Account {
private int no;
private double balance;
public Account() {
}
public Account(int no, double balance) {
this.no = no;
this.balance = balance;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public void withdraw(int n){
double before=this.getBalance();
double after=before-n;
//模拟网络延迟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setBalance(after);
}
}
public class AccountThread extends Thread{
private Account act;
public AccountThread(Account act){
this.act=act;
}
public void run(){
int money=5000;
act.withdraw(money);
System.out.println(Thread.currentThread().getName()+"取款成功"+act.getBalance());
}
}
public class AccountTest {
public static void main(String[] args) {
Account act=new Account(001,10000);
AccountThread T1=new AccountThread(act);
T1.setName("t1");
AccountThread T2=new AccountThread(act);
T2.setName("t2");
T1.start();
T2.start();
}
}
2.使用线程同步机制
public class Account {
private int no;
private double balance;
public Account() {
}
public Account(int no, double balance) {
this.no = no;
this.balance = balance;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public void withdraw(int n) {
synchronized (this) {
double before = this.getBalance();
double after = before - n;
//模拟网络延迟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setBalance(after);
}
}
}
public class AccountThread extends Thread{
private Account act;
public AccountThread(Account act){
this.act=act;
}
public void run(){
int money=5000;
act.withdraw(money);
System.out.println(Thread.currentThread().getName()+"取款成功"+act.getBalance());
}
}
public class AccountTest {
public static void main(String[] args) {
Account act=new Account(001,10000);
AccountThread T1=new AccountThread(act);
T1.setName("t1");
AccountThread T2=new AccountThread(act);
T2.setName("t2");
T1.start();
T2.start();
}
}
synchronized后年的小括号中传的数据必须是多线程共享的对象,才能达到多线程排队。