使用java多线程模拟一个售票系统

简介: 1.基于继承Thread实现代码实现:


1.基于继承Thread实现


代码实现:


/**
 * 多线程模拟售票,基于Thread
 */
public class TicketSalesByThread {
    public static void main(String[] args) {
        SellTicket sellTicket = new SellTicket();
        SellTicket sellTicket1 = new SellTicket();
        SellTicket sellTicket2 = new SellTicket();
        sellTicket.start();
        sellTicket1.start();
        sellTicket2.start();
    }
}
class SellTicket extends Thread {
    // 余票
    private static int ticketNum = 100;
    @Override
    public void run() {
        while (true) {
            if (ticketNum <= 0) {
                System.out.println("没有余票!");
                break;
            }
            // 休眠卖票
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("窗口" + Thread.currentThread().getName() +
                    "售出一张票。" + "剩余票数:" + (--ticketNum));
        }
    }
}


结果分析:


窗口Thread-1售出一张票。剩余票数:97
窗口Thread-0售出一张票。剩余票数:98
窗口Thread-2售出一张票。剩余票数:99
窗口Thread-0售出一张票。剩余票数:96
窗口Thread-1售出一张票。剩余票数:96
窗口Thread-2售出一张票。剩余票数:95
窗口Thread-0售出一张票。剩余票数:94
窗口Thread-1售出一张票。剩余票数:93
窗口Thread-2售出一张票。剩余票数:92
窗口Thread-0售出一张票。剩余票数:91
窗口Thread-1售出一张票。剩余票数:90
窗口Thread-2售出一张票。剩余票数:89
窗口Thread-0售出一张票。剩余票数:88
窗口Thread-1售出一张票。剩余票数:87
窗口Thread-2售出一张票。剩余票数:86
窗口Thread-0售出一张票。剩余票数:85
窗口Thread-1售出一张票。剩余票数:84
窗口Thread-2售出一张票。剩余票数:83
窗口Thread-0售出一张票。剩余票数:82
窗口Thread-1售出一张票。剩余票数:81
窗口Thread-2售出一张票。剩余票数:80
窗口Thread-0售出一张票。剩余票数:79
窗口Thread-1售出一张票。剩余票数:78
窗口Thread-2售出一张票。剩余票数:77
窗口Thread-0售出一张票。剩余票数:76
窗口Thread-1售出一张票。剩余票数:75
窗口Thread-2售出一张票。剩余票数:74
窗口Thread-0售出一张票。剩余票数:73
窗口Thread-1售出一张票。剩余票数:72
窗口Thread-2售出一张票。剩余票数:71
窗口Thread-0售出一张票。剩余票数:70
窗口Thread-1售出一张票。剩余票数:69
窗口Thread-2售出一张票。剩余票数:68
窗口Thread-0售出一张票。剩余票数:67
窗口Thread-1售出一张票。剩余票数:66
窗口Thread-2售出一张票。剩余票数:65
窗口Thread-0售出一张票。剩余票数:64
窗口Thread-1售出一张票。剩余票数:63
窗口Thread-2售出一张票。剩余票数:62
窗口Thread-0售出一张票。剩余票数:61
窗口Thread-1售出一张票。剩余票数:60
窗口Thread-2售出一张票。剩余票数:59
窗口Thread-0售出一张票。剩余票数:58
窗口Thread-1售出一张票。剩余票数:57
窗口Thread-2售出一张票。剩余票数:56
窗口Thread-0售出一张票。剩余票数:55
窗口Thread-1售出一张票。剩余票数:54
窗口Thread-2售出一张票。剩余票数:53
窗口Thread-0售出一张票。剩余票数:52
窗口Thread-1售出一张票。剩余票数:51
窗口Thread-2售出一张票。剩余票数:50
窗口Thread-0售出一张票。剩余票数:49
窗口Thread-1售出一张票。剩余票数:48
窗口Thread-2售出一张票。剩余票数:47
窗口Thread-0售出一张票。剩余票数:46
窗口Thread-1售出一张票。剩余票数:45
窗口Thread-2售出一张票。剩余票数:44
窗口Thread-0售出一张票。剩余票数:43
窗口Thread-1售出一张票。剩余票数:42
窗口Thread-2售出一张票。剩余票数:41
窗口Thread-0售出一张票。剩余票数:40
窗口Thread-1售出一张票。剩余票数:39
窗口Thread-2售出一张票。剩余票数:38
窗口Thread-0售出一张票。剩余票数:37
窗口Thread-1售出一张票。剩余票数:36
窗口Thread-2售出一张票。剩余票数:35
窗口Thread-0售出一张票。剩余票数:34
窗口Thread-1售出一张票。剩余票数:33
窗口Thread-2售出一张票。剩余票数:32
窗口Thread-0售出一张票。剩余票数:31
窗口Thread-1售出一张票。剩余票数:30
窗口Thread-2售出一张票。剩余票数:29
窗口Thread-0售出一张票。剩余票数:28
窗口Thread-1售出一张票。剩余票数:27
窗口Thread-2售出一张票。剩余票数:26
窗口Thread-0售出一张票。剩余票数:25
窗口Thread-1售出一张票。剩余票数:24
窗口Thread-2售出一张票。剩余票数:23
窗口Thread-0售出一张票。剩余票数:22
窗口Thread-1售出一张票。剩余票数:21
窗口Thread-2售出一张票。剩余票数:20
窗口Thread-0售出一张票。剩余票数:19
窗口Thread-1售出一张票。剩余票数:18
窗口Thread-2售出一张票。剩余票数:17
窗口Thread-0售出一张票。剩余票数:16
窗口Thread-1售出一张票。剩余票数:15
窗口Thread-2售出一张票。剩余票数:14
窗口Thread-0售出一张票。剩余票数:13
窗口Thread-1售出一张票。剩余票数:12
窗口Thread-2售出一张票。剩余票数:11
窗口Thread-0售出一张票。剩余票数:10
窗口Thread-1售出一张票。剩余票数:9
窗口Thread-2售出一张票。剩余票数:8
窗口Thread-0售出一张票。剩余票数:7
窗口Thread-1售出一张票。剩余票数:6
窗口Thread-2售出一张票。剩余票数:5
窗口Thread-0售出一张票。剩余票数:4
窗口Thread-1售出一张票。剩余票数:3
窗口Thread-2售出一张票。剩余票数:2
窗口Thread-0售出一张票。剩余票数:1
窗口Thread-1售出一张票。剩余票数:0
没有余票!
窗口Thread-2售出一张票。剩余票数:-1
没有余票!
窗口Thread-0售出一张票。剩余票数:-2
没有余票!


可以看到,基于Thread的实现,出现了明显的超卖现象!😶‍🌫️

那么,为什么会发生这种情况呢?

原因分析:

当一个窗口还未执行--ticketNum操作时,另一个窗口已经进行售票状态,跳过了while循环的限制


2.基于实现Runnable接口实现


代码实现:


/**
 * 多线程模拟售票,基于实现Runnable接口
 */
public class TicketSalesByRunnable {
    public static void main(String[] args) {
        SellTicket02 sellTicket02 = new SellTicket02();
        new Thread(sellTicket02).start();
        new Thread(sellTicket02).start();
        new Thread(sellTicket02).start();
    }
}
class SellTicket02 implements Runnable {
    private int ticketNum = 100;
    @Override
    public void run() {
        while (true) {
            if (ticketNum <= 0) {
                System.out.println("没有余票!");
                break;
            }
            // 休眠卖票
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("窗口" + Thread.currentThread().getName() +
                    "售出一张票。" + "剩余票数:" + (--ticketNum));
        }
    }
}


结果分析:


窗口Thread-0售出一张票。剩余票数:99
窗口Thread-2售出一张票。剩余票数:98
窗口Thread-1售出一张票。剩余票数:98
窗口Thread-0售出一张票。剩余票数:97
窗口Thread-2售出一张票。剩余票数:96
窗口Thread-1售出一张票。剩余票数:95
窗口Thread-0售出一张票。剩余票数:94
窗口Thread-2售出一张票。剩余票数:94
窗口Thread-1售出一张票。剩余票数:93
窗口Thread-2售出一张票。剩余票数:92
窗口Thread-0售出一张票。剩余票数:91
窗口Thread-1售出一张票。剩余票数:90
窗口Thread-2售出一张票。剩余票数:89
窗口Thread-0售出一张票。剩余票数:88
窗口Thread-1售出一张票。剩余票数:87
窗口Thread-0售出一张票。剩余票数:86
窗口Thread-2售出一张票。剩余票数:85
窗口Thread-1售出一张票。剩余票数:84
窗口Thread-2售出一张票。剩余票数:83
窗口Thread-0售出一张票。剩余票数:83
窗口Thread-1售出一张票。剩余票数:82
窗口Thread-2售出一张票。剩余票数:80
窗口Thread-0售出一张票。剩余票数:81
窗口Thread-1售出一张票。剩余票数:79
窗口Thread-2售出一张票。剩余票数:77
窗口Thread-0售出一张票。剩余票数:78
窗口Thread-1售出一张票。剩余票数:76
窗口Thread-2售出一张票。剩余票数:75
窗口Thread-0售出一张票。剩余票数:74
窗口Thread-1售出一张票。剩余票数:73
窗口Thread-2售出一张票。剩余票数:72
窗口Thread-0售出一张票。剩余票数:71
窗口Thread-1售出一张票。剩余票数:70
窗口Thread-2售出一张票。剩余票数:69
窗口Thread-0售出一张票。剩余票数:68
窗口Thread-1售出一张票。剩余票数:67
窗口Thread-2售出一张票。剩余票数:66
窗口Thread-0售出一张票。剩余票数:65
窗口Thread-1售出一张票。剩余票数:64
窗口Thread-2售出一张票。剩余票数:63
窗口Thread-0售出一张票。剩余票数:62
窗口Thread-1售出一张票。剩余票数:61
窗口Thread-2售出一张票。剩余票数:60
窗口Thread-0售出一张票。剩余票数:59
窗口Thread-1售出一张票。剩余票数:58
窗口Thread-2售出一张票。剩余票数:57
窗口Thread-0售出一张票。剩余票数:56
窗口Thread-1售出一张票。剩余票数:55
窗口Thread-2售出一张票。剩余票数:54
窗口Thread-0售出一张票。剩余票数:53
窗口Thread-1售出一张票。剩余票数:52
窗口Thread-2售出一张票。剩余票数:51
窗口Thread-0售出一张票。剩余票数:50
窗口Thread-1售出一张票。剩余票数:49
窗口Thread-2售出一张票。剩余票数:48
窗口Thread-0售出一张票。剩余票数:47
窗口Thread-1售出一张票。剩余票数:46
窗口Thread-2售出一张票。剩余票数:45
窗口Thread-0售出一张票。剩余票数:44
窗口Thread-1售出一张票。剩余票数:43
窗口Thread-2售出一张票。剩余票数:42
窗口Thread-0售出一张票。剩余票数:41
窗口Thread-1售出一张票。剩余票数:40
窗口Thread-2售出一张票。剩余票数:39
窗口Thread-0售出一张票。剩余票数:38
窗口Thread-1售出一张票。剩余票数:37
窗口Thread-2售出一张票。剩余票数:36
窗口Thread-0售出一张票。剩余票数:35
窗口Thread-1售出一张票。剩余票数:34
窗口Thread-2售出一张票。剩余票数:33
窗口Thread-0售出一张票。剩余票数:32
窗口Thread-1售出一张票。剩余票数:31
窗口Thread-2售出一张票。剩余票数:30
窗口Thread-0售出一张票。剩余票数:29
窗口Thread-1售出一张票。剩余票数:28
窗口Thread-2售出一张票。剩余票数:27
窗口Thread-0售出一张票。剩余票数:26
窗口Thread-1售出一张票。剩余票数:25
窗口Thread-2售出一张票。剩余票数:24
窗口Thread-0售出一张票。剩余票数:23
窗口Thread-1售出一张票。剩余票数:22
窗口Thread-2售出一张票。剩余票数:21
窗口Thread-0售出一张票。剩余票数:20
窗口Thread-1售出一张票。剩余票数:19
窗口Thread-2售出一张票。剩余票数:18
窗口Thread-0售出一张票。剩余票数:17
窗口Thread-1售出一张票。剩余票数:16
窗口Thread-2售出一张票。剩余票数:15
窗口Thread-0售出一张票。剩余票数:14
窗口Thread-1售出一张票。剩余票数:13
窗口Thread-2售出一张票。剩余票数:12
窗口Thread-0售出一张票。剩余票数:11
窗口Thread-1售出一张票。剩余票数:10
窗口Thread-2售出一张票。剩余票数:9
窗口Thread-0售出一张票。剩余票数:8
窗口Thread-1售出一张票。剩余票数:7
窗口Thread-2售出一张票。剩余票数:6
窗口Thread-0售出一张票。剩余票数:5
窗口Thread-1售出一张票。剩余票数:4
窗口Thread-2售出一张票。剩余票数:3
窗口Thread-0售出一张票。剩余票数:2
窗口Thread-1售出一张票。剩余票数:1
窗口Thread-2售出一张票。剩余票数:0
没有余票!
窗口Thread-0售出一张票。剩余票数:-1
没有余票!
窗口Thread-1售出一张票。剩余票数:-2
没有余票!


仍然会有超卖现象发生!


3.通知线程退出


有时候,我们需要不同的线程可以相互控制对方的运行

可以采用通知线程中止来解决此类问题,比如我们简单实现一个DEMO,实现主线程通知中止其他线程的效果:


/**
 * 通知线程中止
 */
public class ThreadExit {
    public static void main(String[] args) throws InterruptedException {
        TTT ttt = new TTT();
        ttt.start();
        Thread.sleep(5000);
        // 主线程通知其他线程退出
        ttt.setLoop(false);
    }
}
class TTT extends Thread {
    // 控制变量
    private boolean loop = true;
    @Override
    public void run() {
        while (loop) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("TTT线程正在运行...");
        }
    }
    public void setLoop(boolean loop) {
        this.loop = loop;
    }
}


TTT线程会运行5秒,随后由主线程通知退出🤖


4.解决超卖问题,线程同步机制


在多线程编程中,一些敏感数据不允许被多个线程同时访问,此时就可以使用同步访问技术,保证数据在同一时刻只能有一个线程访问,以保证数据的完整性


synchronized线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作🤖


上成品代码:


/**
 * 使用同步机制解决售票问题的超卖现象
 */
public class TicketSalesResult {
    public static void main(String[] args) {
        SellTicketRes sellTicketRes = new SellTicketRes();
        new Thread(sellTicketRes).start();
        new Thread(sellTicketRes).start();
        new Thread(sellTicketRes).start();
    }
}
class SellTicketRes implements Runnable {
    private int ticketNum = 100;
    private boolean loop = true;
    /**
     * 使用synchronized实现线程同步,解决超卖
     */
    public synchronized void Sell() {
        if (ticketNum <= 0) {
            System.out.println("没有余票!");
            loop = false;
            return;
        }
        // 休眠卖票
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("窗口" + Thread.currentThread().getName() +
                "售出一张票。" + "剩余票数:" + (--ticketNum));
    }
    @Override
     public void run() {
        while (true) {
            if (loop == false) {
                break;
            }
            Sell();
        }
    }
}


结果分析:(完美解决超卖问题)


窗口Thread-0售出一张票。剩余票数:99
窗口Thread-0售出一张票。剩余票数:98
窗口Thread-0售出一张票。剩余票数:97
窗口Thread-0售出一张票。剩余票数:96
窗口Thread-0售出一张票。剩余票数:95
窗口Thread-0售出一张票。剩余票数:94
窗口Thread-0售出一张票。剩余票数:93
窗口Thread-0售出一张票。剩余票数:92
窗口Thread-0售出一张票。剩余票数:91
窗口Thread-0售出一张票。剩余票数:90
窗口Thread-0售出一张票。剩余票数:89
窗口Thread-0售出一张票。剩余票数:88
窗口Thread-0售出一张票。剩余票数:87
窗口Thread-0售出一张票。剩余票数:86
窗口Thread-0售出一张票。剩余票数:85
窗口Thread-0售出一张票。剩余票数:84
窗口Thread-0售出一张票。剩余票数:83
窗口Thread-0售出一张票。剩余票数:82
窗口Thread-0售出一张票。剩余票数:81
窗口Thread-0售出一张票。剩余票数:80
窗口Thread-2售出一张票。剩余票数:79
窗口Thread-2售出一张票。剩余票数:78
窗口Thread-2售出一张票。剩余票数:77
窗口Thread-2售出一张票。剩余票数:76
窗口Thread-2售出一张票。剩余票数:75
窗口Thread-2售出一张票。剩余票数:74
窗口Thread-2售出一张票。剩余票数:73
窗口Thread-2售出一张票。剩余票数:72
窗口Thread-2售出一张票。剩余票数:71
窗口Thread-1售出一张票。剩余票数:70
窗口Thread-1售出一张票。剩余票数:69
窗口Thread-1售出一张票。剩余票数:68
窗口Thread-1售出一张票。剩余票数:67
窗口Thread-1售出一张票。剩余票数:66
窗口Thread-1售出一张票。剩余票数:65
窗口Thread-1售出一张票。剩余票数:64
窗口Thread-1售出一张票。剩余票数:63
窗口Thread-1售出一张票。剩余票数:62
窗口Thread-1售出一张票。剩余票数:61
窗口Thread-1售出一张票。剩余票数:60
窗口Thread-1售出一张票。剩余票数:59
窗口Thread-1售出一张票。剩余票数:58
窗口Thread-1售出一张票。剩余票数:57
窗口Thread-1售出一张票。剩余票数:56
窗口Thread-1售出一张票。剩余票数:55
窗口Thread-1售出一张票。剩余票数:54
窗口Thread-1售出一张票。剩余票数:53
窗口Thread-1售出一张票。剩余票数:52
窗口Thread-1售出一张票。剩余票数:51
窗口Thread-1售出一张票。剩余票数:50
窗口Thread-1售出一张票。剩余票数:49
窗口Thread-1售出一张票。剩余票数:48
窗口Thread-1售出一张票。剩余票数:47
窗口Thread-1售出一张票。剩余票数:46
窗口Thread-1售出一张票。剩余票数:45
窗口Thread-1售出一张票。剩余票数:44
窗口Thread-1售出一张票。剩余票数:43
窗口Thread-1售出一张票。剩余票数:42
窗口Thread-2售出一张票。剩余票数:41
窗口Thread-2售出一张票。剩余票数:40
窗口Thread-2售出一张票。剩余票数:39
窗口Thread-2售出一张票。剩余票数:38
窗口Thread-2售出一张票。剩余票数:37
窗口Thread-2售出一张票。剩余票数:36
窗口Thread-2售出一张票。剩余票数:35
窗口Thread-2售出一张票。剩余票数:34
窗口Thread-2售出一张票。剩余票数:33
窗口Thread-2售出一张票。剩余票数:32
窗口Thread-2售出一张票。剩余票数:31
窗口Thread-2售出一张票。剩余票数:30
窗口Thread-2售出一张票。剩余票数:29
窗口Thread-2售出一张票。剩余票数:28
窗口Thread-2售出一张票。剩余票数:27
窗口Thread-2售出一张票。剩余票数:26
窗口Thread-2售出一张票。剩余票数:25
窗口Thread-2售出一张票。剩余票数:24
窗口Thread-2售出一张票。剩余票数:23
窗口Thread-2售出一张票。剩余票数:22
窗口Thread-2售出一张票。剩余票数:21
窗口Thread-2售出一张票。剩余票数:20
窗口Thread-2售出一张票。剩余票数:19
窗口Thread-2售出一张票。剩余票数:18
窗口Thread-2售出一张票。剩余票数:17
窗口Thread-2售出一张票。剩余票数:16
窗口Thread-0售出一张票。剩余票数:15
窗口Thread-0售出一张票。剩余票数:14
窗口Thread-0售出一张票。剩余票数:13
窗口Thread-0售出一张票。剩余票数:12
窗口Thread-0售出一张票。剩余票数:11
窗口Thread-0售出一张票。剩余票数:10
窗口Thread-0售出一张票。剩余票数:9
窗口Thread-0售出一张票。剩余票数:8
窗口Thread-0售出一张票。剩余票数:7
窗口Thread-2售出一张票。剩余票数:6
窗口Thread-2售出一张票。剩余票数:5
窗口Thread-2售出一张票。剩余票数:4
窗口Thread-2售出一张票。剩余票数:3
窗口Thread-2售出一张票。剩余票数:2
窗口Thread-2售出一张票。剩余票数:1
窗口Thread-2售出一张票。剩余票数:0
没有余票!
没有余票!
没有余票!
目录
相关文章
|
7天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
6天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
|
6天前
|
Java 开发者
Java多线程编程的艺术与实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的技术文档,本文以实战为导向,通过生动的实例和详尽的代码解析,引领读者领略多线程编程的魅力,掌握其在提升应用性能、优化资源利用方面的关键作用。无论你是Java初学者还是有一定经验的开发者,本文都将为你打开多线程编程的新视角。 ####
|
5天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
11天前
|
安全 Java 开发者
深入解读JAVA多线程:wait()、notify()、notifyAll()的奥秘
在Java多线程编程中,`wait()`、`notify()`和`notifyAll()`方法是实现线程间通信和同步的关键机制。这些方法定义在`java.lang.Object`类中,每个Java对象都可以作为线程间通信的媒介。本文将详细解析这三个方法的使用方法和最佳实践,帮助开发者更高效地进行多线程编程。 示例代码展示了如何在同步方法中使用这些方法,确保线程安全和高效的通信。
35 9
|
8天前
|
安全 Java 开发者
Java多线程编程中的常见问题与解决方案
本文深入探讨了Java多线程编程中常见的问题,包括线程安全问题、死锁、竞态条件等,并提供了相应的解决策略。文章首先介绍了多线程的基础知识,随后详细分析了每个问题的产生原因和典型场景,最后提出了实用的解决方案,旨在帮助开发者提高多线程程序的稳定性和性能。
|
11天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
13天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
Java
编写Java程序,车站只剩 50 张从武汉到北京的车票,现有 3 个窗口售卖,用程序模拟售票的过程
编写Java程序,车站只剩 50 张从武汉到北京的车票,现有 3 个窗口售卖,用程序模拟售票的过程
252 0
编写Java程序,车站只剩 50 张从武汉到北京的车票,现有 3 个窗口售卖,用程序模拟售票的过程
|
15天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
下一篇
无影云桌面