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张票
首先,你启动了三个线程,传入相同的对象,那么synchronized代码块的this就会存在锁竞争的情况;其次,线程的synchronized使用的内置锁,内置锁的获取应该是抢占式的,该代码中一次while循环完成后会释放锁,如果此时其他线程还处于等待锁而挂起的状态,那么同一个线程当然有可能刚释放锁就立即又获取到锁。这根线程的调度方式有关。这是我的个人理解,共勉。
t1,t2,t3不是同一个进程
你可以这么写,private static int nums;
加个static关键字