java多线程实在弄不懂
ringa_lee
ringa_lee 2017-04-17 13:35:13
[Java讨论组]

源码如下:
package com.study.test;

/*实现Runnable对象实现多线程
* @author who
* @since 2015-05-05
* */

/*用多线程实现卖票功能
* 一共1000张票,每卖一张票-1
* */
class Ticket implements Runnable {
private int tick = 1000;
boolean bb = true;
public void run() {
// TODO Auto-generated method stub
if (bb) {
while (true) {
if (tick > 0) {
synchronized (this) {
try {
System.out.println("当前boolean值来自run方法:" + bb);
Thread.sleep(20);
System.out.println(Thread.currentThread().getName()
+ "...sale " + tick--);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
} else {
while (true)
SaleTicket();
}
}

public synchronized void SaleTicket() {
    if (tick > 0) {
        try {
            System.out.println("当前boolean值来自SaleTicket方法:" + bb);
            Thread.sleep(20);
            System.out.println(Thread.currentThread().getName()
                    + "...SaleTicket " + tick--);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

}

class TicketDemo {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Ticket t = new Ticket();
    Thread t1 = new Thread(t, "线程1:");
    Thread t2 = new Thread(t, "线程2:");
    Thread t3 = new Thread(t, "线程3:");
    Thread t4 = new Thread(t, "线程4:");
    t1.start();
    Sleep20();
    t.bb = false;
    t2.start();
    Sleep20();
    t.bb = true;
    t3.start();
    Sleep20();
    t.bb = false;
    t4.start();
}

public static void Sleep20() {
    try {
        Thread.sleep(20);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

部分执行输出如下:
当前boolean值来自run方法:true
线程1:...sale 1000
当前boolean值来自run方法:false
线程1:...sale 999
当前boolean值来自SaleTicket方法:true
线程2:...SaleTicket 998
……………………………………
当前boolean值来自run方法:false
线程1:...sale 2
当前boolean值来自run方法:false
线程1:...sale 1
当前boolean值来自run方法:false
线程3:...sale 0
疑问如下:
1、根据代码得知,当bb变量为true时才会进入run方法的同步代码块,否则会进入SaleTicket同步方法中,但是以上输出当前boolean值完全是乱的。
2、针对两个同步代码块都做了同步安全处理,尽然还有“0”值出现,在开启两个线程的情况下不会出现。

ringa_lee
ringa_lee

ringa_lee

全部回复(1)
PHP中文网

run()中,先判断bb值,再进入同步代码段,导致可能出现这种情况:bb值为true, 进入同步代码段前,另一线程修改bb的值为false。同理,synchronized也没有把tick作为临界区保护起来。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号