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 求解 yolo算法问题
  • ¥15 虚拟机打包apk出现错误
  • ¥30 最小化遗憾贪心算法上界
  • ¥15 用visual studi code完成html页面
  • ¥15 聚类分析或者python进行数据分析
  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。