(哈哈哈,代码里面有私心)
线程同步需要队列和锁
三个不安全案例(银行取钱,买票,线程安全)
package BuySticket;
//不安全取钱
public class UnsafeBank {
public static void main(String[] arg) {
Account account = new Account(100,"基金");
Drawing you = new Drawing(account,50,"无畏");
Drawing friend = new Drawing(account,100,"久酷");
you.start();
friend.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() {
super.run();
if(account.money-drawingMoney<0) {
System.out.println(Thread.currentThread().getName()+"钱不够");
return ;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
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 BuySticket;
class unsafe implements Runnable{
int ticketNums= 10;
boolean flag = true;
@Override
public void run() {
// TODO Auto-generated method stub
while (flag) {
Buy();
}
}
private void Buy() {
//判断是否有票
if(ticketNums<=0) {
flag = false;
return ;
}
///模拟延时
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//买票
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
}
}
public class UnsafeBuy {
public static void main(String[] arg) {
unsafe station = new unsafe();
new Thread(station,"无畏").start();
new Thread(station,"久酷").start();
new Thread(station,"Gemini").start();
}
}
package BuySticket;
import java.util.ArrayList;
import java.util.List;
//线程不安全
public class UnsafeList {
public static void main(String[] arg) {
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(list.size());
}
}
锁一个代码块,修改后(锁的对象是变化的两,需要增删改的量)
public void run() {
synchronized(account) {
super.run();
if(account.money-drawingMoney<0) {
System.out.println(Thread.currentThread().getName()+"钱不够");
return ;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//账户剩的钱
account.money = account.money-drawingMoney;
//手里有的钱
nowMoney = nowMoney+drawingMoney;
System.out.println(account.name+"余额为:"+account.money);
System.out.println(Thread.currentThread().getName()+"手里的钱:"+nowMoney);
}
}
JUC安全类型的集合,List替换成CopyOnWriteArrayList