开发者社区> 问答> 正文

Runnable接口多线程问题

源码如下:

/*实现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”值出现,在开启两个线程的情况下不会出现。

展开
收起
蛮大人123 2016-02-27 16:18:44 2066 0
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

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

    2019-07-17 18:49:01
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
多IO线程优化版 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载