线程同步
队列加锁synchronized是实现同步的必要条件。
优先级低的拿到锁,高的没拿到。性能倒置,效率极差
不安全的买票代码实现
//模拟不安全的买票情况
public class SynchronizeTest {
//线程不安全
public static void main(String[] args) {//启动三个线程操纵一份票
BuyTicker buyTicker = new BuyTicker();
new Thread(buyTicker,"我").start();
new Thread(buyTicker,"你").start();
new Thread(buyTicker,"黄牛").start();
}
}
class BuyTicker implements Runnable{
private int ticketNum = 10;
boolean flag = true; //利用标志位结束run()方法
@Override
public void run() {
while(flag){//外部停止方式
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void buy() throws InterruptedException {//sleep()要抛出中断异常
//判断是否有票
if(ticketNum<=0){
System.out.println("票卖完了");
flag = false;
return;
}
Thread.sleep(1000);//延时是为了看出效果,不然cpu运算太快了
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNum--);
}
}
不安全银行代码
public class UnsafeBake {
public static void main(String[] args) {
Account account = new Account("结婚基金",100);
Draw you = new Draw(account,50,"你");
Draw girlFriend = new Draw(account,100,"女朋友");
you.start();
girlFriend.start();
}
}
class Account{//账户类,初始化一个账户
String name;
int money;
public Account(String name, int money) {
this.name = name;
this.money = money;
}
}
class Draw extends Thread{//取钱类
Account account;//需要账户,
int drawMoney;//取款金额
int noMoney;//账户余额
public Draw(Account account, int drawMoney, String name) {
super(name);//初始化谁,取了多少钱
this.account = account;
this.drawMoney = drawMoney;
}
@Override
public void run() {
if(account.money-drawMoney<0){//取钱判断
System.out.println("余额不足");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money = account.money - drawMoney;
noMoney = noMoney +drawMoney;
System.out.println(account.name+"余额为:"+account.money);//取完钱提示你取出多少,余额多少
System.out.println(this.getName()+"手里的钱"+noMoney);//继承THread可以直接写this
}
}
不安全的列表
import java.util.ArrayList;
import java.util.List;
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();
}
System.out.println(list.size());
}
}