线程安全的误解: 线程安全并不是否定资源共享

线程安全的误解: 线程安全并不是否定资源共享

(2010-08-04 17:36:48)
标签:

线程安全

杂谈

分类:java和数据库

  • 之所以造成这个误解,大概跟线程安全的几种解决手段有关.
目前公认的几种线程安全的解决手段:
  1. 同步技术
  2. 多用方法内局部变量
  3. ThreadLocal技术(一线程,一实例变量copy)
除同步技术外,另两种解决手段都是"anti_sharing",实际是牺牲了多并发线程下的资源的共享特性.


  • 线程安全的定义:
多线程的共享资源的实际值会和理论值 不一致,这样就叫作"线程不安全"
多线程对共享资源的改变,也是理论值之一.即理论上是接受共享资源被多个线程改变的.

  • 举例如下:
我们举最常见的"多线程售票"的例子,很多人在学习多线程都是从这个例子开始的.
下面这段程序是存在线程安全问题的,但"共享售票"并不意味着线程不安全
public class MyThread implements Runnable {
    private intticket = 5; // 一共才5张票,会被多线程共同卖出

    public voidrun() {
       for (int i =0; i < 50; i++) {
          if (this.ticket > 0){
            System.out.println("卖票:ticket = " + this.ticket--);
          }
       }
    }
}

    publicstatic void main(String[] args) {
       MyThread mt= new MyThread(); // 单实例
       newThread(mt).start();    //一个线程开始卖票
       newThread(mt).start();    //另一个线程开始卖票
       newThread(mt).start();    //再一个线程开始卖票
    }
执行:
卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1

因为程序执行太快了,来不及显性产生线程安全问题,我们在run()中加一个Thread.sleep(300)方法
    publicvoid run() {
       for (int i =0; i < 50; i++) {
          if (this.ticket >0) {
             try {
                Thread.sleep(300);// 延迟
             } catch(InterruptedException e) {
               e.printStackTrace();
             }
            System.out.println("卖票:ticket = " + this.ticket--);
运行结果如下:
D:\java\source\thread\sync>javasyndemo.SynDemo01
卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1
卖票:ticket = 0
卖票:ticket = -1             这就是理论值(this.ticket> 0)实际值(-1)不符,
                              反映了线程安全的概念定义
原因:
当剩最后一张票时
上一个进程通过了(this.ticket >0)的判断,却sleep了,没来得及把this.ticket--
而另一个进程趁机也通过了(this.ticket > 0)的判断
这样就形成了ticket=1时两个线程都通过测试,都进行了--,就出现了-1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值