多线程售票系统(包含三种常见的线程安全策略)

创建多线程的四种方法

1、继承Thread类(不推荐);
2、实现Runnable接口;
3、实现Callable接口;
4、线程池(推荐)。

常见的三种线程安全策略

1、同步代码块;
2、同步方法;
3、同步锁。

示例:实现Runnable接口

public class SellTicket implements Runnable {
	private int ticktNum = 121;
	Object obj = new Object();
	@Override
	public void run() {
                //同步代码块解决线程安全问题。
		synchronized (obj) {
			while (ticktNum > 0) {
				// 开始出票
				// 线程名称
				String name = Thread.currentThread().getName();
				// 票数相减
				System.out.println("线程名称:" + name + " 票号:" + ticktNum--);
			}
		}
	}
}
public class Tx {
	public static void main(String[] args) {
	    SellTicket st=new SellTicket();
	    Thread thread1 = new Thread(st, "窗口1");
            Thread thread2 = new Thread(st, "窗口2");
            Thread thread3 = new Thread(st, "窗口3");
	    Thread thread4 = new Thread(st, "窗口4");
            Thread thread5 = new Thread(st, "窗口5");
            thread1.start();
            thread2.start();
            thread3.start();
            thread4.start();
            thread5.start();
	}
}	

示例:实现Callable接口

import java.util.concurrent.Callable;

public class SellTicket implements Callable<Integer> {
	private int ticktNum = 100;
	@Override
	public Integer call() throws Exception {
		sellTicket();
		//返回剩余票数
		return ticktNum;
	}
        //同步方法解决线程安全问题。
	private synchronized void sellTicket() throws Exception{
		while (ticktNum > 0) {
			Thread.sleep(10);
			// 开始出票
			// 线程名称
			String name = Thread.currentThread().getName();
			// 票数相减
			System.out.println("线程名称:" + name + " 票号:" + ticktNum--);
		}
	}
}

import java.util.concurrent.FutureTask;

public class Tx {
	public static void main(String[] args) throws Exception {
		FutureTask task = new FutureTask(new SellTicket());

		Thread thread1 = new Thread(task);
		Thread thread2 = new Thread(task);
		Thread thread3 = new Thread(task);
		Thread thread4 = new Thread(task);
		Thread thread5 = new Thread(task);

		thread1.start();
		thread2.start();
		thread3.start();
		thread4.start();
		thread5.start();

		// 返回值
		System.out.println(task.get());
	}
}

示例:线程池

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//注意:ExecutorService需要已经实现了Runnable的类来配合使用。
public class SellTicket implements Runnable {
	private int ticktNum = 10;
	Object obj = new Object();
	// true表示公平锁,默认false表示非公平锁。
	Lock lock = new ReentrantLock(true);

	@Override
	public void run() {
		// 同步锁块解决线程安全问题。
		while (true) {
			//开启锁
			lock.lock();
			if (ticktNum > 0) {
				try {
					// 开始出票
					// 线程名称
					String name = Thread.currentThread().getName();
					// 票数相减
					System.out.println("线程名称:" + name + " 票号:" + ticktNum--);
				} catch (Exception e) {
					// TODO: handle exception
				} finally {
					// 释放锁
					lock.unlock();
				}
			}else {
				break;
			}
		}
	}
}
public class Tx {
	public static void main(String[] args) throws Exception {
		ExecutorService executorService=Executors.newFixedThreadPool(5);
		SellTicket sellTicket = new SellTicket();
		executorService.execute(sellTicket);
		executorService.execute(sellTicket);
		executorService.execute(sellTicket);
		executorService.execute(sellTicket);
		executorService.execute(sellTicket);
	}
}
发布了124 篇原创文章 · 获赞 119 · 访问量 51万+

猜你喜欢

转载自blog.csdn.net/qq_39706570/article/details/104635761