栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Java语言面向对象】(92)线程同步问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Java语言面向对象】(92)线程同步问题

多线程运行模式,一般有两种:

卖票属于多个线程共享一份资源。

拿卖票来举例子

显然不正确

因为两个线程共跑了20次

希望,两个线程共跑10次。

整改

package com.njwbhz.march.week2.part0310.Ticket;

class Ticket {

    private int number = 10;

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}

卖票线程

package com.njwbhz.march.week2.part0310.Ticket;

public class Seller implements  Runnable {
    Ticket ticket = new Ticket();

    public Seller(Ticket ticket) {
        this.ticket = ticket;
    }

    @Override
    public void run() {
        //synchronized (惟一的对象)
//        synchronized (this) {//this指的是Seller,而Seller只有一个
//            //把可能造成不安全事件的代码锁起来
//            while (ticket.getNumber() > 0) {
//                //卖一张票
//                ticket.setNumber(ticket.getNumber() - 1);
            System.out.println(Thread.currentThread().getName() + ":" + "卖了一张票,还剩下" + ticket.getNumber() + "张");
//                try {
//                    Thread.sleep(500);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println(Thread.currentThread().getName() + ":" + "卖了一张票,还剩下" + ticket.getNumber() + "张");
//            }
//        }
//        while (ticket.getNumber() > 0) {
//            synchronized (this) {
//                //卖一张票
//                ticket.setNumber(ticket.getNumber() - 1);
            System.out.println(Thread.currentThread().getName() + ":" + "卖了一张票,还剩下" + ticket.getNumber() + "张");
//                try {
//                    Thread.sleep(500);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println(Thread.currentThread().getName() + ":" + "卖了一张票,还剩下" + ticket.getNumber() + "张");
//            }
//        }

//
        while (true) {

            synchronized (this) {
                if (ticket.getNumber() <= 0) {
                    break;
                }
                //卖一张票
                ticket.setNumber(ticket.getNumber() - 1);
//            System.out.println(Thread.currentThread().getName() + ":" + "卖了一张票,还剩下" + ticket.getNumber() + "张");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" + "卖了一张票,还剩下" + ticket.getNumber() + "张");
            }

        }
        //锁的位置要适当
        //锁的位置不对,仍然不安全
    }

    private synchronized void sell () {//Seller.class类锁
        if (ticket.getNumber() == 0) {
            System.exit(0);
        }
        if (ticket.getNumber() > 0){
            //卖一张票
            ticket.setNumber(ticket.getNumber() - 1);
//            System.out.println(Thread.currentThread().getName() + ":" + "卖了一张票,还剩下" + ticket.getNumber() + "张");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":" + "卖了一张票,还剩下" + ticket.getNumber() + "张");
        }
    }
}

用两个窗口同时卖票,启动两个Seller线程

package com.njwbhz.march.week2.part0310.Ticket;

public class SellerApp {
    public static void main(String[] args) {
        //只new一次说明只有一份数据
        Ticket ticket = new Ticket();

        Seller seller = new Seller(ticket);

        Thread t1 = new Thread(seller);
        Thread t2 = new Thread(seller);

        t1.setName("窗口张");
        t2.setName("窗口李");

        t1.start();
        t2.start();
    }
}

分析:为什么会造成数据不一致问题,CPU轮转不受程序员的控制。

当多个线程共享一份数据,且对数据发生修改操作时,会造成数据不安全,这种现象称为线程不安全事件,或线程同步问题。

怎么解决?

JDK中的锁机制

测试

至少看到一点进步,数据安全了,但是只能有一个线程做事。

synchronized 既可以锁代码块,也可以锁方法,最终能够保证数据的安全性。

synchronized牺牲了性能,提高了数据的安全性。

回顾集合框架

如何甄别线程同步问题

什么叫数据域?

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/759889.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号