1、買票案例
(1)實作介面,創建買票的執行緒:
public class BuyTickets implements Runnable { private int ticketNum=10; boolean flag=true; @Override public void run() { while (flag){ buy(); } } private void buy(){ if(ticketNum<=0){ flag=false; return; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNum--+"張票"); } }
(2)創建三個執行緒進行測驗:
public class Test { public static void main(String[] args) { BuyTickets buyTickets=new BuyTickets(); new Thread(buyTickets,"zhai").start(); new Thread(buyTickets,"zhang").start(); new Thread(buyTickets,"zhao").start(); } }
(3)測驗結果:
zhao拿到了第10張票
zhang拿到了第10張票
zhai拿到了第9張票
zhai拿到了第8張票
zhang拿到了第7張票
zhao拿到了第6張票
zhai拿到了第5張票
zhang拿到了第4張票
zhao拿到了第3張票
zhai拿到了第2張票
zhang拿到了第1張票
zhao拿到了第0張票
zhai拿到了第-1張票
十號票被賣兩次的原因是:
zhang拿到第10張票后,發現數量是大于0的,可以繼續執行,但是沒有搶占到CPU資源,接著,zhao拿到第10張票以后,獲得了CPU資源,執行完畢后,才輪到zhang執行
zhai得到-1票的原因:
有多個人拿到了同一張票,在第1個減一后變為1,第二個人減一后變為0,第三個人減一后變為-1
2、銀行取錢
(1)繼承Thread類,創建取錢的執行緒:
public class BankTest extends Thread{ Account account; int drawingMoney;//取出的金額 int nowMoney;//現金 public BankTest(Account account,int drawingMoney,String name){ super(name); this.account=account; this.drawingMoney=drawingMoney; } public void run(){ //判斷是否有余額 if(account.money-drawingMoney<0){ System.out.println("余額不足"); return; } try { Thread.sleep(1000);//放大問題的發生性 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("余額:"+account.money); account.money=account.money-drawingMoney;//余額 nowMoney=nowMoney+drawingMoney; System.out.println(this.getName()+"現金:"+nowMoney); } }
(2)創建賬戶類:
public class Account { int money;//余額 String name;//名字 public Account(int money, String name) { this.money = money; this.name = name; } }
(3)創建測驗類:
public class Test { public static void main(String[] args) { Account account=new Account(1000,"工資"); BankTest bankTest1=new BankTest(account,150,"tom"); BankTest bankTest2=new BankTest(account,200,"jack"); bankTest1.start(); bankTest2.start(); } }
(4)測驗結果又幾種不同的情況:
余額:1000 tom現金:150 余額:1000 jack現金:200
余額:1000 余額:1000 tom現金:150 jack現金:200
余額:1000 jack現金:200 余額:800 tom現金:150
余額:1000 余額:1000 jack現金:200 tom現金:150
產生這種情況的原因是,可能兩個執行緒同時呼叫了run方法,但是一個執行緒獲得了CPU,一個執行緒未獲得CPU沒有辦法執行,只有它執行之后另外一個等待的執行緒才能執行,
3、執行緒不安全的集合
public class UnSafeList { public static void main(String[] args) { List<String> list=new ArrayList<String>(); for(int i=0;i<10000;i++){ new Thread(()->{ list.add(Thread.currentThread().getName()); }).start(); } try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); } }
兩個執行緒同一瞬間操作了同一個位置,將元素覆寫掉了,因此,集合的長度小于預期值,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/178299.html
標籤:Java
上一篇:Mysql面試的技術名詞
