方式一:继承thread 类
每个线程100张票
package com.example.starter;
public class SellTickets extends Thread{
public static void main(String[] args) {
Thread t1 = new SellTick1();
Thread t2 = new SellTick1();
Thread t3 = new SellTick1();
t1.start();
t2.start();
t3.start();
}
}
class SellTick1 extends Thread{
private int num = 100;
@Override
public void run(){
while(true){
if(num <= 0){
System.out.println("售票结束");
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (--num ));
}
}
}
结果:
方式二:num 使用static修饰
一共100张票 有重复减票的情况,最后还有减成负数的情况
package com.example.starter;
public class SellTickets extends Thread{
public static void main(String[] args) {
Thread t1 = new SellTick1();
Thread t2 = new SellTick1();
Thread t3 = new SellTick1();
t1.start();
t2.start();
t3.start();
}
}
class SellTick1 extends Thread{
private static int num = 100;
@Override
public void run(){
while(true){
if(num <= 0){
System.out.println("售票结束");
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (--num));
}
}
}
结果:
方式三:实现runnable的方式
package com.example.starter;
public class SellTickets extends Thread{
public static void main(String[] args) {
SellTicket2 sellTicket2 = new SellTicket2();
Thread t1 = new Thread(sellTicket2);
Thread t2 = new Thread(sellTicket2);
Thread t3 = new Thread(sellTicket2);
t1.start();
t2.start();
t3.start();
}
}
class SellTicket2 implements Runnable{
private int num = 100;
@Override
public void run() {
while(true){
if(num <= 0){
System.out.println("售票结束");
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
num --;
System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (num));
}
}
}
结果
方式四:以上三种方式多存在多售票的问题,使用synchronized优化
package com.example.starter;
public class SellTickets extends Thread{
public static void main(String[] args) {
SellTicket2 sellTicket2 = new SellTicket2();
Thread t1 = new Thread(sellTicket2);
Thread t2 = new Thread(sellTicket2);
Thread t3 = new Thread(sellTicket2);
t1.start();
t2.start();
t3.start();
}
}
class SellTicket2 implements Runnable{
private volatile int num = 100;
private volatile boolean loop = true;
@Override
public void run() {
while(loop){
sell();
}
}
synchronized void sell(){
if(num <= 0){
System.out.println("售票结束");
loop = false;
return;
}
num --;
System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (num));
}
}
结果:
方式五:
package com.example.starter;
public class SynSellTickets extends Thread{
public static void main(String[] args) {
SellTicket3 sellTicket3 = new SellTicket3();
Thread t1 = new Thread(sellTicket3);
Thread t2 = new Thread(sellTicket3);
Thread t3 = new Thread(sellTicket3);
t1.start();
t2.start();
t3.start();
}
}
class SellTicket3 implements Runnable{
private int num = 100;
private boolean loop = true;
@Override
public void run() {
while(loop){
synchronized (this){
if(num > 0){
num --;
System.out.println("窗口"+Thread.currentThread().getName()+ "售出 一张票 剩余票数=" + (num));
}else{
loop = false;
}
}
}
System.out.println("售票结束");
}
}
结果:



