当前位置: 代码迷 >> 综合 >> JavaThread 10 并发问题 → 三大不安全案例
  详细解决方案

JavaThread 10 并发问题 → 三大不安全案例

热度:92   发布时间:2023-11-24 13:49:03.0

5.1 并发问题 → 三大不安全案例


5.1.1 三人共同买票(不安全买票)

package www.muquanyu.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 ticket = 10;@Overridepublic void run() {
    //买票while(ticket > 0){
    try {
    Thread.sleep(100);} catch (InterruptedException e) {
    e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "-->买到了第"+(ticket--)+"张票");}}
}

在这里插入图片描述
明显会有 资源 抢夺的问题,这里会 出现 资源的重复,这是根本不可能的事情!!(所以这是 并发问题 的发生。)


5.1.2 两人共同取款(不安全取款)

package www.muquanyu.syn;public class UnsafeBank {
    public static void main(String[] args) {
    //账户创建Account account = new Account(100,"结婚基金");Drawing you = new Drawing(account,50,"你");Drawing grilFriend = new Drawing(account,100,"你的女朋友");you.start();grilFriend.start();}
}//账户(Java 版本的结构体)
class Account{
    int money;//余额String name;//卡名public Account( int money,String name){
    this.money = money;this.name = name;}public Account(String name){
    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;}@Overridepublic void run() {
    //判断有没有钱if(account.money - drawingMoney < 0){
    System.out.println(Thread.currentThread().getName()+"-->抱歉你的钱不够!");return;}try {
    Thread.sleep(100);} catch (InterruptedException e) {
    e.printStackTrace();}account.money -= drawingMoney;//你手里的钱nowMoney += drawingMoney;System.out.println(account.name+"余额为:"+account.money);System.out.println(this.getName()+"手里的钱:"+nowMoney);}
}

在这里插入图片描述
嗯? 那 五十万呢??我草?
在这里插入图片描述
… 全没了。。
在这里插入图片描述
过分了啊,负数。。

综上所述,这些操作 都是 不安全的,会出现 并发问题。


5.1.3 线程不安全的集合


package www.muquanyu.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();}System.out.println(list.size());}
}

我们往往 处理 数据,是不是都是在 集合里面处理的呀?那比如说我们 每一个数据 都开个 线程处理!我们的数据 还会是正确的吗?

在这里插入图片描述
为什么是不正确的呢?答:因为多个线程 同时 对 一个 List 集合 进行 存储的操作!!发生了 并发问题。


5.1.4 CopyOnWriteArrayList(JUC)

我们来说一个 JUC(Java 并发包)下的 安全 集合。

Callable 这个可能会成为 新时代宠儿的 接口,就是 JUC 包下面的。

package www.muquanyu.syn;import java.util.concurrent.CopyOnWriteArrayList;//JUC 安全类型的 集合
public class JUCDemo {
    public static void main(String[] args) throws InterruptedException {
    CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();for(int i = 0;i < 10000;++i){
    new Thread(()->{
    list.add(Thread.currentThread().getName());}).start();}Thread.sleep(100);System.out.println(list.size());}
}

在这里插入图片描述
JUC 包下 的 CopyOnWriteArrayList<> 是 一个 安全的 集合。