案例1:不安全买票,出现重复买票、或出现负数
加上 synchronized
package com.pln.syn;//不安全买票//可能出现负数public class UnsafeBuyTicket {public static void main(String[] args) {BuyTicket buyTicket = new BuyTicket();new Thread(buyTicket,"小明").start();new Thread(buyTicket,"老手").start();new Thread(buyTicket,"黄牛").start();}}class BuyTicket implements Runnable{// 票private int ticketNumber = 10;boolean flag = true;@Overridepublic void run() {while (flag){try {buy();} catch (InterruptedException e) {e.printStackTrace();}}}// 在private后边加上 synchronized同步方法,锁的是this//就会进行排队private 【synchronized】 void buy() throws InterruptedException {if(ticketNumber <= 0){flag = false;System.out.println(Thread.currentThread().getName()+"票卖完了");return ;}Thread.sleep(100);//模拟延时System.out.println(Thread.currentThread().getName()+"------>"+ticketNumber--);}}
案例二:账户余额会出现负数
package com.pln.syn;//不安全取钱//两个人到银行取钱,账户public class UnsafeBank {public static void main(String[] args) {Account account = new Account("结婚基金",100);Drawing drawing = new Drawing(account,50,"小明");Drawing girlFriends = new Drawing(account,100,"girlFriends");drawing.start();girlFriends.start();}}//账户class Account {String name;//账户名字int money;//余额public Account(String name, int money) {this.name = name;this.money = money;}}//银行模拟取款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("没有钱了");return;}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}account.money = account.money - drawingMoney;nowMoney = nowMoney + drawingMoney;System.out.println(account.name+"余额"+account.money);System.out.println(Thread.currentThread().getName()+"现在手里有"+nowMoney);}}//解决问题//增加同步代码块//锁的对象是变化的量,增删改public void run(){synchronized (account){// 判断有没有钱if(account.money - drawingMoney <0){System.out.println("钱不够了,不能取钱");return;}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}account.money = account.money - drawingMoney;nowMoney = nowMoney + drawingMoney;System.out.println(account.name+"余额"+account.money);System.out.println(Thread.currentThread().getName()+"现在手里有"+nowMoney);}}
案例三:线程不安全集合
package com.pln.syn;
import java.util.ArrayList;
import java.util.List;
//线程不安全集合
public class UnsafeList {
public static void main(String[] args) throws InterruptedException {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
Thread.sleep(3000);
System.out.println(list.size());
}
}
//正确的修改
for (int i = 0; i < 10000; i++) {
synchronized (list){
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
}

不是10000,所以不安全,有的被覆盖了
修改正确的结果:


