執行緒三大不安全案例&同步方法及同步塊
阿新 • • 發佈:2022-12-01
執行緒三大不安全案例&同步方法及同步塊
執行緒三大不安全案例
買票
package com.deng.syn; //不安全的買票 //執行緒不安全,有負數 public class UnsafeBuyTicket { public static void main(String[] args) { BuyTicket station = new BuyTicket(); new Thread(station, "我").start(); new Thread(station, "你").start(); new Thread(station, "黃牛黨").start(); } } class BuyTicket implements Runnable { //票 private int ticketNums = 10; boolean flag = true;//外部停止方式 @Override public void run() { //買票 while (flag) { try { buy(); } catch (InterruptedException e) { e.printStackTrace(); } } } private void buy() throws InterruptedException { //判斷是否有票 if (ticketNums <= 0) { flag = false; return; } //模擬延時 Thread.sleep(200); //買票 System.out.println(Thread.currentThread().getName() + "拿到" + ticketNums--); } }
銀行取錢
package com.deng.syn; //不安全的取錢 //兩個人去銀行取錢,賬戶 public class UnsafeBank { public static void main(String[] args) { //賬戶 Account account = new Account(100, "結婚基金"); Drawing you = new Drawing(account, 50, "You"); Drawing me = new Drawing(account, 100, "Me"); you.start(); me.start(); } } //賬戶 class Account { int money;//餘額 String name;//卡名 public Account(int money, String name) { this.money = money; this.name = name; } } //銀行:模擬取款 class Drawing extends Thread { Account account;//賬戶 //取了多少錢 int drawingMoney; //現在手裡有多少錢 int nowMoney; public Drawing(Account account, int drawingMoney, String name) { super(name); this.account = account; this.drawingMoney = drawingMoney; } //取錢 @Override public void run() { //判斷有沒有錢 if (account.money - drawingMoney < 0) { System.out.println(Thread.currentThread().getName() + "錢不夠,取不了"); return; } //sleep放大問題的發生性 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //卡內餘額 = 餘額-你取的錢 account.money = account.money - drawingMoney; //你手裡的錢 nowMoney = nowMoney + drawingMoney; System.out.println(account.name + "餘額為:" + account.money); //Thread.currentThread().getName()=this.getName(); System.out.println(this.getName() + "手裡的錢:" + nowMoney); } }
集合
package com.deng.syn; import java.util.ArrayList; import java.util.List; public class UnsafeList { public static void main(String[] args) { List<String> list = new ArrayList<>(); for (int i = 0; i < 10000; i++) { new Thread(()->{ list.add((Thread.currentThread().getName())); }).start(); } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); } }
同步方法及同步塊
-
同步方法
public synchronized void method(int args){}
-
同步塊
synchronized(obj){}
補充:JUC
package com.deng.syn;
import java.util.concurrent.CopyOnWriteArrayList;
//測試JUC安全型別的集合
public class TestJUC {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
for (int i = 0; i < 10000; i++) {
new Thread(() -> {
list.add(Thread.currentThread().getName());
}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}