博客
关于我
线程同步机制和三个线程不安全例子
阅读量:365 次
发布时间:2019-03-05

本文共 3130 字,大约阅读时间需要 10 分钟。

并发与锁机制

在并发编程中,多个线程同时操作同一资源时,会出现访问冲突的问题。为了确保访问的正确性,Java引入了锁机制(synchronized),通过加锁和释放锁来控制资源的访问。然而,锁机制也伴随着一些问题:

  • 加锁会导致其他线程必须等待,影响性能。
  • 加锁和释放锁会频繁切换上下文,增加系统调度延时。
  • 线程优先级问题可能导致性能下降。
  • 抢票不安全

    以下示例展示了线程不安全导致的数据紊乱。每个线程都试图从票盘中抢票,当票数为0时,线程停止运行。由于没有同步机制,多个线程可能在同一时间修改票数,导致票数出现负数。

    public class UnsafeBuyTicket {    public static void main(String[] args) {        Myticket myticket = new Myticket();        new Thread(myticket, "用户1").start();        new Thread(myticket, "用户2").start();        new Thread(myticket, "用户3").start();    }}class Myticket implements Runnable {    private int tickets = 10;    boolean flag = true;    @Override    public void run() {        while (flag) {            try {                buy();            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    private void buy() throws InterruptedException {        while (flag) {            if (tickets <= 0) {                flag = false;                return;            }            Thread.sleep(100);            System.out.println(Thread.currentThread().getName() + "抢到了第" + tickets-- + "张票");        }    }}

    结果:抢票结果会出现负数,线程不安全。

    同时取钱不安全

    以下示例展示了线程不安全导致的账户余额问题。每个线程尝试从账户中取款,当账户余额不足时,线程停止运行。由于没有同步机制,多个线程可能在同一时间修改账户余额,导致余额出现负数。

    public class UnsafaBank {    public static void main(String[] args) {        Account account = new Account(100, "卡内");        Drawing drawing01 = new Drawing(account, 50, "用户1");        Drawing drawing02 = new Drawing(account, 100, "用户2");        drawing01.start();        drawing02.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;    }    @Override    public void run() {        if (account.money - drawingmoney < 0) {            System.out.println(Thread.currentThread().getName() + "钱不够,请修改金额");            return;        }        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        account.money -= drawingmoney;        nowmoney = nowmoney + drawingmoney;        System.out.println(account.name + "余额为:" + account.money);        System.out.println(Thread.currentThread().getName() + "取出" + nowmoney);    }}

    结果:线程不安全,两个线程同时对一个资源操作时,出现余额为负数。

    线程不安全

    List是Java中的一个常用集合类,用于存储和操作一系列的对象。ArrayList、LinkedList和Vector都是List的实现类。以下示例展示了线程不安全的影响:当多个线程同时尝试向列表添加元素时,可能会导致元素覆盖。

    public class UnsafeList {    public static void main(String[] args) {        List
    list = new ArrayList<>(); for (int i = 0; i < 10000; i++) { new Thread(() -> { list.add(Thread.currentThread().getName()); }).start(); } try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); }}

    结果:由于多个线程同时将线程名加入列表,导致覆盖,列表没有达到10000个元素。

    转载地址:http://nimg.baihongyu.com/

    你可能感兴趣的文章
    2020 AI 产业图谱启动,勾勒中国 AI 技术与行业生态
    查看>>
    Netty4服务端入门代码示例
    查看>>
    Spring源码:prepareBeanFactory(beanFactory);方法
    查看>>
    AcWing 828. 模拟栈
    查看>>
    (20200328已解决)从docker容器内复制文件到宿主机
    查看>>
    理解Docker ulimit参数
    查看>>
    OpenAI Gym简介及初级实例
    查看>>
    int 转 CString
    查看>>
    Edit编辑框自动换行与长度
    查看>>
    Java面向对象
    查看>>
    JAVA带标签的break和continue
    查看>>
    Java获取线程基本信息的方法
    查看>>
    vue源码分析(MVVM篇)
    查看>>
    设计模式之组合模式
    查看>>
    (Python学习笔记):字典
    查看>>
    (C++11/14/17学习笔记):线程启动、结束,创建线程多法、join,detach
    查看>>
    leetcode 14 最长公共前缀
    查看>>
    做做Java
    查看>>
    C++并发与多线程(一)
    查看>>
    计算机网络子网划分错题集
    查看>>