多线程资源共享的问题

以此文来反驳网上一片博文:Java中Runnable和Thread的区别

http://blog.chinaunix.net/uid-20665441-id-310538.html,这两个哪个是原创不分了

Runnable并不能解决资源共享。

废话不多说,上代码:

public class Demo implements Runnable {
    private static final Logger logger = Logger.getLogger(Demo.class);

    String name;
    static Integer tickets = 20;

    public Demo(String name) {
        this.name = name;
    }

    public void run() {
        for (int i = 1; i <= 20; i++) {
            if (tickets > 0) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                logger.info("我取票了" + ": " + tickets);
                tickets -= 1;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                logger.info("==========我取走了" + ": " + tickets);
            }
        }
    }

    public static void main(String[] args) throws IOException {

        Demo demo = new Demo("hello");

        new Thread(demo).start();
        new Thread(demo).start();
        new Thread(demo).start();

    }
}
结果:

[Thread-1] 我取票了: 20  
[Thread-2] 我取票了: 20  
[Thread-0] 我取票了: 20  
[Thread-1] ==========我取走了: 17  
[Thread-2] ==========我取走了: 17  
[Thread-0] ==========我取走了: 17  
[Thread-1] 我取票了: 17  
[Thread-2] 我取票了: 16  
[Thread-0] 我取票了: 15  
[Thread-1] ==========我取走了: 14  
[Thread-2] ==========我取走了: 14  
[Thread-0] ==========我取走了: 14  
[Thread-1] 我取票了: 14  
[Thread-2] 我取票了: 14  
[Thread-0] 我取票了: 12  
[Thread-1] ==========我取走了: 11  
[Thread-2] ==========我取走了: 11  
[Thread-0] ==========我取走了: 11  
[Thread-1] 我取票了: 11  
[Thread-2] 我取票了: 10  
[Thread-0] 我取票了: 9  
[Thread-1] ==========我取走了: 8  
[Thread-2] ==========我取走了: 8  
[Thread-0] ==========我取走了: 8  
[Thread-2] 我取票了: 8  
[Thread-1] 我取票了: 8  
[Thread-0] 我取票了: 6  
[Thread-2] ==========我取走了: 5  
[Thread-1] ==========我取走了: 5  
[Thread-0] ==========我取走了: 5  
[Thread-1] 我取票了: 5  
[Thread-2] 我取票了: 5  
[Thread-0] 我取票了: 3  
[Thread-1] ==========我取走了: 2  
[Thread-2] ==========我取走了: 2  
[Thread-0] ==========我取走了: 2  
[Thread-2] 我取票了: 2  
[Thread-1] 我取票了: 2  
[Thread-0] 我取票了: 0  
[Thread-1] ==========我取走了: -1  
[Thread-2] ==========我取走了: -1  
[Thread-0] ==========我取走了: -1  

从上面结果看到,最后出现负数,所以 仅仅依靠Runnable是不能解决资源共享问题的

那么如何解决呢?

办法1. 同步run()方法

public synchronized void run()

输出结果为:

[Thread-0] 我取票了: 20  
[Thread-0] ==========我取走了: 19  
[Thread-0] 我取票了: 19  
[Thread-0] ==========我取走了: 18  
[Thread-0] 我取票了: 18  
[Thread-0] ==========我取走了: 17  
[Thread-0] 我取票了: 17  
[Thread-0] ==========我取走了: 16  
[Thread-0] 我取票了: 16  
[Thread-0] ==========我取走了: 15  
[Thread-0] 我取票了: 15  
[Thread-0] ==========我取走了: 14  
[Thread-0] 我取票了: 14  
[Thread-0] ==========我取走了: 13  
[Thread-0] 我取票了: 13  
[Thread-0] ==========我取走了: 12  
[Thread-0] 我取票了: 12  
[Thread-0] ==========我取走了: 11  
[Thread-0] 我取票了: 11  
[Thread-0] ==========我取走了: 10  
[Thread-0] 我取票了: 10  
[Thread-0] ==========我取走了: 9  
[Thread-0] 我取票了: 9  
[Thread-0] ==========我取走了: 8  
[Thread-0] 我取票了: 8  
[Thread-0] ==========我取走了: 7  
[Thread-0] 我取票了: 7  
[Thread-0] ==========我取走了: 6  
[Thread-0] 我取票了: 6  
[Thread-0] ==========我取走了: 5  
[Thread-0] 我取票了: 5  
[Thread-0] ==========我取走了: 4  
[Thread-0] 我取票了: 4  
[Thread-0] ==========我取走了: 3  
[Thread-0] 我取票了: 3  
[Thread-0] ==========我取走了: 2  
[Thread-0] 我取票了: 2  
[Thread-0] ==========我取走了: 1  
[Thread-0] 我取票了: 1  
[Thread-0] ==========我取走了: 0  


办法2. 同步tickets?这种方法貌似很行哦(⊙o⊙),Really?

public void run() {
    for (int i = 1; i <= 20; i++) {
        synchronized (tickets) {
            if (tickets > 0) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                logger.info("我取票了" + ": " + tickets);
                tickets -= 1;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                logger.info("==========我取走了" + ": " + tickets);
            }
        }
    }
}
输出结果为:

[Thread-0] 我取票了: 20  
[Thread-0] ==========我取走了: 19  
[Thread-2] 我取票了: 19  
[Thread-0] 我取票了: 19  
[Thread-2] ==========我取走了: 17  
[Thread-0] ==========我取走了: 17  
[Thread-2] 我取票了: 17  
[Thread-1] 我取票了: 16  
[Thread-1] ==========我取走了: 15  
[Thread-2] ==========我取走了: 15  
[Thread-0] 我取票了: 15  
[Thread-1] 我取票了: 15  
[Thread-0] ==========我取走了: 13  
[Thread-1] ==========我取走了: 13  
[Thread-1] 我取票了: 13  
[Thread-2] 我取票了: 13  
[Thread-1] ==========我取走了: 11  
[Thread-2] ==========我取走了: 11  
[Thread-0] 我取票了: 11  
[Thread-1] 我取票了: 11  
[Thread-1] ==========我取走了: 9  
[Thread-0] ==========我取走了: 9  
[Thread-1] 我取票了: 9  
[Thread-2] 我取票了: 9  
[Thread-1] ==========我取走了: 7  
[Thread-2] ==========我取走了: 7  
[Thread-0] 我取票了: 7  
[Thread-2] 我取票了: 7  
[Thread-2] ==========我取走了: 5  
[Thread-0] ==========我取走了: 5  
[Thread-2] 我取票了: 5  
[Thread-1] 我取票了: 5  
[Thread-2] ==========我取走了: 3  
[Thread-1] ==========我取走了: 3  
[Thread-2] 我取票了: 3  
[Thread-0] 我取票了: 2  
[Thread-2] ==========我取走了: 1  
[Thread-0] ==========我取走了: 1  
[Thread-2] 我取票了: 1  
[Thread-1] 我取票了: 1  
[Thread-2] ==========我取走了: -1  
[Thread-1] ==========我取走了: -1  
上面输出结果中,两个线程同时进来取票,最后出现负数,貌似是可以说明Integer不支持线程同步的,

因为 tickets-- 等同于tickets = new Integer(tickets-1),tickets早已不是原来的那个tickets。所以方法2是行不通的。

但是,如果存放“票”的是List却是完全可以的!


博主刚开始学线程,有误之处,欢迎指正!~

~~~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值