QQ1058386071 2016-10-15 10:46 采纳率: 0%
浏览 3260

synchronized同步问题:三个线程同时加载一个对象,为什么一个线程能连续运行多次?

package com.day14;

public class demo14 {

public static void main(String[] args) {
    // TODO 自动生成的方法存根

    demo14 de=new demo14();
}
public demo14()
{
    TicketWindow tw1=new TicketWindow();

    Thread t1=new Thread(tw1);
    Thread t2=new Thread(tw1);
    Thread t3=new Thread(tw1);
    t1.start();
    t2.start();
    t3.start();
}

}
class TicketWindow implements Runnable

{

private  int nums=2000;

public void run() {
    // TODO 自动生成的方法存根
    while(true){
        synchronized (this) {

            if(nums>0)
            {
                System.out.println(Thread.currentThread().getName()+
                        "正在售出第"+nums+"张票");

                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        // TODO 自动生成的 catch 块
                        e.printStackTrace();
                    }

                    // TODO 自动生成的 catch 块


                nums--;
            }
            else
                break;

        }
    }

}

}
结果:
Thread-1正在售出第2000张票
Thread-1正在售出第1999张票
Thread-2正在售出第1998张票
Thread-2正在售出第1997张票
Thread-0正在售出第1996张票
Thread-2正在售出第1995张票
Thread-2正在售出第1994张票
Thread-1正在售出第1993张票
Thread-1正在售出第1992张票
Thread-1正在售出第1991张票
Thread-1正在售出第1990张票
Thread-1正在售出第1989张票
Thread-1正在售出第1988张票
Thread-1正在售出第1987张票
把睡眠提到对象锁前面同一个线程就不会连续运行
class TicketWindow implements Runnable

{

private  int nums=2000;

public void run() {
    // TODO 自动生成的方法存根
    while(true){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        synchronized (this) {

            if(nums>0)
            {
                System.out.println(Thread.currentThread().getName()+
                        "正在售出第"+nums+"张票");





                    // TODO 自动生成的 catch 块


                nums--;
            }
            else
                break;

        }
    }

}

}
结果
Thread-0正在售出第2000张票
Thread-2正在售出第1999张票
Thread-1正在售出第1998张票
Thread-0正在售出第1997张票
Thread-1正在售出第1996张票
Thread-2正在售出第1995张票
Thread-1正在售出第1994张票
Thread-0正在售出第1993张票
Thread-2正在售出第1992张票
Thread-1正在售出第1991张票
Thread-0正在售出第1990张票
Thread-2正在售出第1989张票
Thread-1正在售出第1988张票
Thread-0正在售出第1987张票
Thread-2正在售出第1986张票

  • 写回答

3条回答

  • 毕小宝 博客专家认证 2016-10-15 12:42
    关注
     首先,你启动了三个线程,传入相同的对象,那么synchronized代码块的this就会存在锁竞争的情况;其次,线程的synchronized使用的内置锁,内置锁的获取应该是抢占式的,该代码中一次while循环完成后会释放锁,如果此时其他线程还处于等待锁而挂起的状态,那么同一个线程当然有可能刚释放锁就立即又获取到锁。这根线程的调度方式有关。这是我的个人理解,共勉。
    
    评论

报告相同问题?

悬赏问题

  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥20 Python安装cvxpy库出问题
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥15 python天天向上类似问题,但没有清零
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题