博客
关于我
线程同步机制和三个线程不安全例子
阅读量: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/

    你可能感兴趣的文章
    Linux网络属性配置详解
    查看>>
    Python(三十)类的理解
    查看>>
    Extjs布局详解
    查看>>
    Android数据库
    查看>>
    HTML基础,块级元素/行内元素/行内块元素辨析【2分钟掌握】
    查看>>
    keil左侧文件调整方法
    查看>>
    本地分支关联远程分支
    查看>>
    STM8 GPIO模式
    查看>>
    python多态和封装
    查看>>
    STM32boot启动
    查看>>
    回调函数(callback function)
    查看>>
    omnet++
    查看>>
    23种设计模式一:单例模式
    查看>>
    Qt中的析构函数
    查看>>
    CSharp中委托(一)委托、匿名函数、lambda表达式、多播委托、窗体传值、泛型委托
    查看>>
    二叉堆的c++模板类实现
    查看>>
    C语言实现dijkstra(adjacence matrix)
    查看>>
    SQL Server SQL语句调优技巧
    查看>>
    用C#实现封装-徐新帅-专题视频课程
    查看>>
    C语言学习从初级到精通的疯狂实战教程-徐新帅-专题视频课程
    查看>>