多线程的四种方法

多线程的四种方法

同步代码块

同步代码块用synchronized锁定当前要执行的代码块;

多个线程都对同一个对象操作时,同一时间这个对象的同步代码块只能被一个线程执行。

import java.util.concurrent.TimeUnit;
public class MultiThreadSellTicket implements Runnable {
	/*
	 * 多线程售票第一版 使用同步代码块,让线程在操作同一个资源时互斥
	 */
	int totalTicket = 50;
	int leftTicket = totalTicket;
	Object obj = new Object();

	/*
	 * 线程要做的操作: 判断当前剩余票数是否大于0, 如果大于0就让当前剩余票数减一, 减一之前的值作为卖出去的票打印。 如果剩余票数不大于0,线程结束
	 */
	@Override
	public void run() {
		String name = Thread.currentThread().getName();
		// 优化后(将耗时操作,并且不需要线程互斥执行的逻辑,放到同步块外面)
		while (leftTicket > 0) {
			synchronized (obj) {
				if (leftTicket <= 0) {
					System.out.println("[" + name + "]票卖完了");
					break;
				}
				int ticketNo = totalTicket - leftTicket + 1;
				System.out.println("【" + name + "】 卖出编号为:" + ticketNo + "的票!");
				leftTicket--;
			}
			try {
				TimeUnit.MILLISECONDS.sleep(300);
			} catch (Exception e) {
			}
		}
	}
	public static void main(String[] args) throws Exception {
		MultiThreadSellTicket task = new MultiThreadSellTicket();
		long start = System.currentTimeMillis();
		Thread thread1 = new Thread(task, "窗口1");
		Thread thread2 = new Thread(task, "窗口2");
		Thread thread3 = new Thread(task, "窗口3");
		thread1.start();
		thread2.start();
		thread3.start();
		// 让主线程等待三个窗口都卖完
		thread1.join();
		thread2.join();
		thread3.join();
		long end = System.currentTimeMillis();
		System.out.println("三个窗口卖出全部票耗时:" + (end - start) + "ms");
	}
}

同步方法块

同步⽅法是指在实例⽅法声明的时候添加 synchronized 关键字,多线程同一个时间调用次方法时,只有一个线程可以调用,其他线程等待。

多个线程都对同一个对象操作时,同一时间这个对象的同步方法块只能被一个线程执行调用。

import java.util.concurrent.TimeUnit;

public class MultiThreadSellTicket2 implements Runnable {
	/*
	 * 多线程售票都二版 使用同步方法,让线程在操作同一个资源时,只有一个线程可以调用
	 */
	int totalTicket = 50;
	int leftTicket = totalTicket;
	Object obj = new Object();

	/*
	 * 线程要做的操作: 判断当前剩余票数是否大于0, 如果大于0就让当前剩余票数减一, 减一之前的值作为卖出去的票打印。 如果剩余票数不大于0,线程结束
	 */
	@Override
	public void run() {
		while (true) {MultiThreadSellTicket3 task1 = new MultiThreadSellTicket3();
			sellTicket();
			if (leftTicket <= 0) {
				break;
			}
		}
	}
	public synchronized void sellTicket() {
		String name = Thread.currentThread().getName();
		// 优化后(将耗时操作,并且不需要线程互斥执行的逻辑,放到同步块外面)
		if (leftTicket <= 0) {
			System.out.println("[" + name + "]票卖完了");
			return;
		}
		int ticketNo = totalTicket - leftTicket + 1;
		System.out.println("【" + name + "】 卖出编号为:" + ticketNo + "的票!");
		leftTicket--;
		try {
			TimeUnit.MILLISECONDS.sleep(300);
		} catch (Exception e) {
		}
	}
	public static void main(String[] args) throws Exception {
		MultiThreadSellTicket2 task = new MultiThreadSellTicket2();
		long start = System.currentTimeMillis();
		Thread thread1 = new Thread(task, "窗口1");
		Thread thread2 = new Thread(task, "窗口2");
		Thread thread3 = new Thread(task, "窗口3");
		thread1.start();
		thread2.start();
		thread3.start();
		// 让主线程等待三个窗口都卖完
		thread1.join();
		thread2.join();
		thread3.join();
		long end = System.currentTimeMillis();
		System.out.println("三个窗口卖出全部票耗时:" + (end - start) + "ms");
	}
}

同步静态代码块

同步静态代码块与同步代码块使⽤⽅法类似,但是同步静态块锁定的时当前类的class。

同步静态块中的代码同⼀时间只能被⼀个线程调⽤,⽆论这些线程是否访问的是不是同⼀个对象。

import java.util.concurrent.TimeUnit;

public class MultiThreadSellTicket3 implements Runnable {
	/*
	 * 多线程售票都三版 使用同步静态代码块,让线程在操作同一个资源时,只有一个线程可以调用
	 */

	static int totalTicket = 50;
	static int leftTicket = totalTicket;

	/*
	 * 线程要做的操作: 判断当前剩余票数是否大于0, 如果大于0就让当前剩余票数减一, 减一之前的值作为卖出去的票打印。 如果剩余票数不大于0,线程结束
	 */
	@Override
	public void run() {
		String name = Thread.currentThread().getName();
		while (leftTicket > 0) {
			synchronized (MultiThreadSellTicket3.class) {
				if (leftTicket <= 0) {
					System.out.println("[" + name + "]票卖完了");
					return;
				}
				int ticketNo = totalTicket - leftTicket + 1;
				System.out.println("【" + name + "】 卖出编号为:" + ticketNo + "的票!");
				leftTicket--;

				try {
					TimeUnit.MILLISECONDS.sleep(300);
				} catch (Exception e) {
				}
			}
		}
	}

	public static void main(String[] args) throws Exception {
		// 创建线程
		MultiThreadSellTicket3 task1 = new MultiThreadSellTicket3();
		MultiThreadSellTicket3 task2 = new MultiThreadSellTicket3();
		MultiThreadSellTicket3 task3 = new MultiThreadSellTicket3();

		long start = System.currentTimeMillis();
		Thread thread1 = new Thread(task1, "窗口1");
		Thread thread2 = new Thread(task2, "窗口2");
		Thread thread3 = new Thread(task3, "窗口3");
		thread1.start();
		thread2.start();
		thread3.start();
		// 让主线程等待三个窗口都卖完
		thread1.join();
		thread2.join();
		thread3.join();

		long end = System.currentTimeMillis();
		System.out.println("三个窗口卖出全部票耗时:" + (end - start) + "ms");

	}
}

同步静态方法块

同步静态⽅法与同步⽅法使⽤⽅法类似,所不同的是,同步静态⽅法锁定的是当前类的class。

同步静态⽅法中的代码同⼀时间只能被⼀个线程调⽤,⽆论这些线程是否访问的是不是同⼀个对象。

import java.util.concurrent.TimeUnit;

public class MultiThreadSellTicket4 implements Runnable {
	/*
	 * 多线程售票第四版 使用同步静态方法,同⼀时间只能被⼀个线程调用,无论这些线程是否访问的是不是同⼀个对象。
	 */

	static int totalTicket = 50;
	static int leftTicket = totalTicket;

	/*
	 * 线程要做的操作: 判断当前剩余票数是否大于0, 如果大于0就让当前剩余票数减一, 减一之前的值作为卖出去的票打印。 如果剩余票数不大于0,线程结束
	 */
	@Override
	public void run() {
		while (true) {
			MultiThreadSellTicket3 task1 = new MultiThreadSellTicket3();
			sellTicket();
			if (leftTicket <= 0) {
				break;
			}
		}

	}

	public static synchronized void sellTicket() {
		String name = Thread.currentThread().getName();
		// 优化后(将耗时操作,并且不需要线程互斥执行的逻辑,放到同步块外面)
		if (leftTicket <= 0) {
			System.out.println("[" + name + "]票卖完了");
			return;
		}
		int ticketNo = totalTicket - leftTicket + 1;
		System.out.println("【" + name + "】 卖出编号为:" + ticketNo + "的票!");
		leftTicket--;
		try {
			TimeUnit.MILLISECONDS.sleep(300);
		} catch (Exception e) {
		}
	}

	public static void main(String[] args) throws Exception {
		MultiThreadSellTicket4 task = new MultiThreadSellTicket4();
		long start = System.currentTimeMillis();
		Thread thread1 = new Thread(task, "窗口1");
		Thread thread2 = new Thread(task, "窗口2");
		Thread thread3 = new Thread(task, "窗口3");
		thread1.start();
		thread2.start();
		thread3.start();

		// 让主线程等待三个窗口都卖完
		thread1.join();
		thread2.join();
		thread3.join();

		long end = System.currentTimeMillis();
		System.out.println("三个窗口卖出全部票耗时:" + (end - start) + "ms");

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值