博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java学习——线程同步问题
阅读量:3946 次
发布时间:2019-05-24

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

Java学习——线程同步问题

多线程在共同操作一个变量的时候可能会产生问题,这个我们在之前的多个线程卖票案例中也给大家提到过,那么我们今天就来解决一下这个问题。会用到一个关键字synchronized,如下:

/** * 多个线程买票:安全 */public class UnsafeBuyTicket implements Runnable {    //定义总票数    private int ticketNum=10;    //定义标记    private boolean flag=true;    //重写的run方法    @Override    public void run() {        //如果标记为true,则调用买票方法        while (flag){            buyTicket();        }    }    //synchronized:锁    //线程安全实现机制:队列+锁    private synchronized void buyTicket() {        //判断票数是否小于等于0,如果票数小于等于0则将标记改为false        if (ticketNum<=0){            flag=false;            //return结束方法            return;        }        try {            //模拟网络延迟            Thread.sleep(200);        } catch (InterruptedException e) {            e.printStackTrace();        }        //打印票数        System.out.println(Thread.currentThread().getName()+"买到了第"+(ticketNum--)+"张票");    }    //主方法,开启三个线程操作一个对象    public static void main(String[] args) {        UnsafeBuyTicket unsafeBuyTicket = new UnsafeBuyTicket();        new Thread(unsafeBuyTicket,"小明001").start();        new Thread(unsafeBuyTicket,"小方002").start();        new Thread(unsafeBuyTicket,"小杭003").start();    }}

那么为什么用了synchronized这个关键字就会安全了,线程安全的实现机制就是队列+锁,我们在一个线程进入操作数据的时候,其他线程在外面排队等候,并将这个数据锁起来,就不会产生线程不安全了。

再看以下案例:

public class SafeList {    public static void main(String[] args) throws InterruptedException {        ArrayList
list = new ArrayList<>(); for (int i = 0; i < 10000; i++) { new Thread(()->{ list.add("1"); }).start(); } for (int i = 5; i > 0; i--) { Thread.sleep(1000); System.out.println("倒计时"+i); } System.out.println(list.size()); }}

输出:

倒计时5倒计时4倒计时3倒计时2倒计时19999

我们发现本来集合的大小因该是10000,但是最后却输出的是9999.那么我们给线程加上锁试试:

public class SafeList {    public static void main(String[] args) throws InterruptedException {        ArrayList
list = new ArrayList<>(); for (int i = 0; i < 10000; i++) { new Thread(()->{ //我们知道是因为list添加数据线程不安全的,那么我们在这里用同步代码块将其锁住即可 synchronized (list){ list.add("1"); } }).start(); } for (int i = 5; i > 0; i--) { Thread.sleep(1000); System.out.println("倒计时"+i); } System.out.println(list.size()); }}

输出:

倒计时5倒计时4倒计时3倒计时2倒计时110000

同步代码块默认锁住的是this,我们视情况而定,看是哪个会发生资源的共用,分析是哪里导致线程不安全就锁住哪里。

有同步代码块就有同步方法,同步方法只能锁住的是this,就比如上面的卖票案例,就是利用的是同步方法。

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

你可能感兴趣的文章
允許文本框輸入數字,退格鍵,小數點,負號
查看>>
SOLR的一些错误
查看>>
Linux下python升级步骤
查看>>
关于mongodb ,redis,memcache
查看>>
DEDECMS BUG汇总
查看>>
html5 常用
查看>>
node-webkit:开发桌面+WEB混合型应用的神器
查看>>
Hybird APP 开发 总结
查看>>
创业公司进行股权激励要注意的四大问题
查看>>
Ext各组件属性配置(上) -- 中文注释
查看>>
document.forms用法
查看>>
[手机知道] 用IE7调试 JS报没有权限
查看>>
JS 定义数组
查看>>
PHP解决多线程同时读写一个文件的…
查看>>
PHP一段上传文件的代码
查看>>
猴子排队算法
查看>>
猴子排队算法
查看>>
查询系统负载信息&nbsp;Linux&nbsp;命令详解
查看>>
增强&nbsp;SSH&nbsp;安全性的&nbsp;7&nbsp;条技巧
查看>>
this作用域、javascript面向…
查看>>