Java------多线程_并发_非同步_三大经典案例 (七)
线程同步要保证数据的安全性和正确性,以及性能。
代码上使用synon
高性能、高并发、高可用
并发:同一个对象多个线程同时 *** 作。
并发的三个条件缺一不可,同一对象、多个线程、同时 *** 作。
之前模拟抢票代码时,多个线程同时对一份资源进行 *** 作,导致出现两种数据错误的表现:
1.抢到最后出现负数的情况。
2.抢的过程中出现多个线程使用同一票数的情况。多个线程从主存空间拷贝到各自工作内存中数据不一致。
public class ThreadSyn { public static void main(String[] args) { UnSafe threadTest01 = new UnSafe(); //多个代理,加入名称区分 new Thread(threadTest01,"thread01").start(); new Thread(threadTest01,"thread02").start(); new Thread(threadTest01,"thread03").start(); } } class UnSafe implements Runnable{ private int tickNums = 10; private Boolean flag = true; @Override public void run(){ while (flag){ test(); } } public void test(){ if (tickNums<0){ flag = false; return; } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--->"+tickNums--); } }
案例二:同时取钱的例子,即使在取钱时,加入判断,依然能取出去,造成账户余额为负数,两个人都能取到钱。
public class ThreadSyn02 { public static void main(String[] args) { Account account = new Account(100,"家庭基金"); Draw draw = new Draw(account,70,"男人"); Draw draw2 = new Draw(account,70,"女人"); draw.start(); draw2.start(); } } //账户 Account class Account{ public int money; public String name; public Account(int money, String name) { this.money = money; this.name = name; } } class Draw extends Thread{ Account account; //账户 int drawingMoney;//取的钱 int packetTotal;//口袋里的钱 public Draw(Account account,int drawingMoney,String name){ super(name); this.account = account; this.drawingMoney = drawingMoney; } @Override public void run() { //加上判断,当银行余额-取钱小于0时,不让取 if (account.money-drawingMoney<0){ return; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } account.money -= drawingMoney; packetTotal += drawingMoney; System.out.println(this.getName()+"---->账户余额"+account.money); System.out.println(this.getName()+"---->口袋余额"+packetTotal); } }
案例三:容器一会出现线程不安全
public class ThreadSyn03 { public static void main(String[] args) { ArrayListarrayList = new ArrayList (); for (int i = 0 ; i<100;i++){ new Thread(()->{ arrayList.add(Thread.currentThread().getName()); }).start(); } //最终打印结果,不到100 System.out.println(arrayList.size()); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)