- 启用了四个线程,但是只有一个窗口在卖票。
public class SellTicketTest {
public static void main(String[] args) {
TicketSell t1 = new TicketSell();
TicketSell t2 = new TicketSell();
TicketSell t3 = new TicketSell();
TicketSell t4 = new TicketSell();
t1.setName("第一号窗口");
t2.setName("第二号窗口");
t3.setName("第三号窗口");
t4.setName("第四号窗口");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class TicketSell extends Thread {
private static int ticket = 10;
@Override
public void run() { //在循环开始外围进行同步代码块,当第一个线程进入的时候,因为一直在循环所以代码没有执行完
//其他的线程不能执行该同步代码块的代码
synchronized (TicketSell.class) {
while (ticket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName() + "卖出第 " + ticket + "号票");
ticket--;
}
}
}
}
image.png
在循环开始外围进行同步代码块,当第一个线程进入的时候,因为一直在循环所以代码没有执行完,其他的线程不能执行该同步代码块的代码。所以,在写同步代码块的时候,注意不要把循环也包含在内。
- 对代码进行修改后,问题二:卖出负数号票
class TicketSell extends Thread {
private static int ticket = 10;
@Override
public void run() {
while (ticket > 0) {
synchronized (TicketSell.class) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName() + "卖出第 " + ticket + "号票");
ticket--;
}
}
}
}
image.png
2,3,4号线程,满足ticket>0,会进入while循环,但是此刻1号线程正在执行同步代码块,待其执行完后, 2,3,4号线程会分别执行同步代码块。导致出现负数。
- 继续修改代码,最终正确执行。
class TicketSell extends Thread {
private static int ticket = 20;
@Override
public void run() {
while (true) {
synchronized (TicketSell.class) {
if (ticket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName() + "卖出第 " + ticket + "号票");
ticket--;
} else {
break;
}
}
}
}
}
image.png
网友评论