线程同步
线程同步也就是线程的并发,是指多个线程同时访问一个资源,这时候因为只有一个资源,就需要出现排队的机制,就比如买车票,如果没有队列的机制,就有可能多个人在同一时间购买到了同一张票,这就会导致问题的出现,线程同步其实就是一种等待的机制,多个访问时就会形成一个对象的等待池,前一个结束才会到下一个,该线程还没有结束时,就会有个锁机制(synchronized),确保线程独占资源,让其他线程等待,线程结束释放锁.。
同步并发的方式有两种,一种是在方法上添加synchronized修饰,另一种则是为同步修改的数据添加同步块synchronized(Obj){},
第一种方法同步的话是对this而言,就是对象本身或者class,有些时候就会出现错误。第二种方法较好。
这里我们用一个银行取钱的例子
public class BankMoney {
public static void main(String[] args) {
Account account=new Account(100,"储蓄");
Bank you=new Bank(account,50,"you");
Bank wife=new Bank(account,100,"wife");
you.start();
wife.start();
}
}
class Account{
int money;//账户余额
String name;//账户名
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
class Bank extends Thread{
Account account;//账户
int getmoney;//取了多少钱
int hasmoney;//手里有多少钱
public Bank(Account account, int getmoney,String name) {
super(name);
this.account = account;
this.getmoney = getmoney;
}
@Override
public void run() {
synchronized (account){
if (account.money-getmoney<0){
System.out.println(Thread.currentThread().getName()+"没钱了,不能取");
return;
}
//sleep放大问题
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//卡内余额
account.money-=getmoney;
// 手上的钱
hasmoney+=getmoney;
System.out.println(account.name+"余额为:"+account.money);
System.out.println(Thread.currentThread().getName()+"手里的钱为:"+hasmoney);
}
}
}
如果不使用同步块,同步监视器,两线程就会同时取钱,就会出现错误
如下图,余额就会出现负数,肯定是错误的