synchronized
多线程操作统一资源(临界资源)时,需要同步机制;
队列和锁
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) { // TODO Auto-generated catch block e.printStackTrace(); } } } private void buy() throws InterruptedException { //判断是否有票 if(ticketNums<=0) { flag=false; return; } //模拟延时 Thread.sleep(100); //买票 System.out.println(Thread.currentThread().getName()+"拿到了"+ticketNums--); } }
不安全的取钱(银行)
package synchronize; //两个人去银行取钱,账户 public class UnsafeBank { public static void main(String[] args) { Account account=new Account(100,"结婚基金"); Drawing you =new Drawing(account,50,"你"); Drawing girlfriend =new Drawing(account,100,"girlfriend"); you.start(); girlfriend.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; } //取钱方法 public void run() { //先判断有没有钱 if (account.money-drawingMoney<0) { System.out.println(Thread.currentThread().getName()+"钱不够,取不出来!"); return; } try {//增加延时,放大问题发生性 Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //卡内余额=余额-取出的钱; account.money-=drawingMoney; //手里的钱 nowMoney += drawingMoney; System.out.println(account.name+"余额为:"+account.money); System.out.println(this.getName()+"手里的钱为:"+nowMoney); } }
线程不完全的集合
import java.util.List; import java.util.ArrayList; //线程不安全的集合 public class MyTest { public static void main(String[] args) throws InterruptedException { List<String> list = new ArrayList<>(); for (int i = 0; i < 10000; i++) { new Thread(()->{ list.add(Thread.currentThread().getName() ); }).start(); } Thread.sleep(2000); System.out.println(list.size()); } }