java实现多线程的两种方式
1、继承Thread类 ,public class TestThread extend Thread{}
2实现Runnable接口,public class TestThred implements Runnable{}
没有同步的情况下,代码如下
//账户类
public class Account {
private double balance;
public double deposit(double money){
double newMoney=balance+money;
try{
Thread.sleep(10);
}catch (Exception e){
}
balance=newMoney;
return money;
}
public double getBalance(){
return balance;
}
}
//充钱线程类
public class AddMoney implements Runnable{
private Account account;
private double money;
public AddMoney(Account account, double money) {
this.account = account;
this.money = money;
}
@Override
public void run() {
account.deposit(money);
}
}
//测试类
public class Test {
public static void main(String[] arges){
Account account=new Account();
ExecutorService executorService=Executors.newFixedThreadPool(100);//创建线程池
for (int i = 0; i <100 ; i++) {
executorService.execute(new AddMoney(account,1));
}
executorService.shutdown();
while(!executorService.isTerminated()) {}
System.out.println(account.getBalance());
}
}
输出结果为10以下的数字,因为线程不同步,每次线程获取的账户余额不不是最新的数据,导致数据有误,解决办法有以下两个,一是使用synchronized 关键字使线程同步,二是为每个银行账户创建一个锁对象,在存款操作进行加锁和解锁的操作
1、账户同步
//账户类
public class Account {
private double balance;
public synchronized double deposit(double money){
double newMoney=balance+money;
try{
Thread.sleep(10);
}catch (Exception e){
}
balance=newMoney;
return money;
}
public double getBalance(){
return balance;
}
}
2run方法内account同步
//充钱线程类
public class AddMoney implements Runnable{
private Account account;
private double money;
public AddMoney(Account account, double money) {
this.account = account;
this.money = money;
}
@Override
public void run() {
synchronized (account) {
account.deposit(money);
}
}
}
加锁
public class Account {
private Lock accountAccount=new ReentrantLock();//锁对象
private double balance;
public double deposit(double money){ accountAccount.lock();//加锁
double newMoney=balance+money;
try{
Thread.sleep(10);
}catch (Exception e){
}
balance=newMoney;
accountAccount.unlock();//解锁
return money;
}
public double getBalance(){
return balance;
}
}
上面3种方式输出结果为100,正确