同步代码块、静态同步方法、非静态同步方法的锁分别是:

  • 同步代码块可以使用自定义的Object对象,也可以使用this或者当前类的字节码文件(类名.class);
  • 静态同步方法的锁是当前类的字节码文件(类名.class);
  • 非静态同步方法的锁是this;

证明方法:

  • 两个线程之间实现同步,一个线程使用同步代码块,一个线程使用同步方法。
  • 如果这两个线程同步了,说明了使用的是同一个锁;
创建线程类(以售票为例)
/**
 * @methodDesc 售票线程类
 */
public class ThreadTrain extends Thread {
	// 总共又100张
	private static int trainCount = 100;	
	protected static boolean flag = true;

	@Override
	public void run() {		
		while (trainCount > 0) {
			if (flag) { // 执行同步代码块,this锁
				System.out.println("flag==="+flag);
				// 出售火车票
				sale1();		
			}else {
				System.out.println("flag==="+flag);
				// 出售火车票
				sale11();
			}
			flag = !flag;
		}
	}
	
	// 同步代码块
	public void sale1() {
		// 同步代码块,包裹需要解决线程安全问题的代码块,两个线程同时访问
		synchronized (this) { // 只能有一个线程进行访问,必须拿到锁的时候才能访问
			if (trainCount > 0) { // 不加判断,会出现出售第101张票的情况
				System.out.println(Thread.currentThread().getName() + ", 出售第" + (100 - trainCount + 1) + "张票");
				trainCount--;
			}
		}
	}
	
	// 静态同步代码块
	public void sale2() {
		// 同步代码块,包裹需要解决线程安全问题的代码块,两个线程同时访问
		synchronized (ThreadTrain.class) { // 只能有一个线程进行访问,必须拿到锁的时候才能访问
			if (trainCount > 0) { // 不加判断,会出现出售第101张票的情况
				System.out.println(Thread.currentThread().getName() + ", 出售第" + (100 - trainCount + 1) + "张票");
				trainCount--;
			}
		}
	}

	// 同步方法
	public synchronized void sale11() {		
		if (trainCount > 0) { // 不加判断,会出现出售第101张票的情况
			System.out.println(Thread.currentThread().getName() + ", 出售第" + (100 - trainCount + 1) + "张票");
			trainCount--;
		}
	}
	
	// 静态同步方法
	public static synchronized void sale22() {		
		if (trainCount > 0) { // 不加判断,会出现出售第101张票的情况
			System.out.println(Thread.currentThread().getName() + ", 出售第" + (100 - trainCount + 1) + "张票");
			trainCount--;
		}
	}
}
创建测试类
/**
 * @methodDesc 多线程模拟售票问题
 */
public class ThreadDemo {
	public static void main(String[] args) throws InterruptedException {
		// 创建售票线程对象
		ThreadTrain train1 = new ThreadTrain();
		// 创建多个售票窗口,并给其取别名
		Thread t1 = new Thread(train1, "窗口1");
		Thread t2 = new Thread(train1, "窗口2");
		t1.start();	
		t2.start();
	}
}
验证方法
  • 验证非静态同步方法,修改run方法为
        public void run() {		
		while (trainCount > 0) {
			if (flag) { // 执行同步代码块,this锁
				System.out.println("flag==="+flag);
				// 出售火车票
				sale1();		
			}else {
				System.out.println("flag==="+flag);
				// 出售火车票
				sale11();
			}
			flag = !flag;
		}
	}
  • 验证静态同步方法,修改run方法为
        public void run() {		
		while (trainCount > 0) {
			if (flag) { // 执行同步代码块,this锁
				System.out.println("flag==="+flag);
				// 出售火车票
				sale2();		
			}else {
				System.out.println("flag==="+flag);
				// 出售火车票
				sale22();
			}
			flag = !flag;
		}
	}
posted on 2019-03-17 19:04  luoyu113  阅读(379)  评论(0编辑  收藏  举报