Java复习之知识点整理(七)----多线程的安全机制

Part1、同步代码块
------------------------------------------
1.同步代码块括起来的代码,在同一时间只会进入一个分线程
2.同步代码块 synchorized 使用的注意事项
①锁lock必须是同一个,唯一的
②能不加同步尽量不加,即使加了锁,也要保证最少的代码加锁(锁最主要的代码),从而保证效率
3.语法: synchorized(锁){ ... }

Part2、同步方法
-----------------------------------------
1.注意:同步非方法的锁是当前对象(new出来的),同步的静态方法的锁是类本身。
2.语法:public static synchorized void func1(){ ..... }
3.通常将要同步的代码抽取成一个对象,例如 票池,然后再票池中定义同步方法


Part1,2代码展示:

public class Ts01 {
	public static void main(String[] args) {
		TicketPool t = new TicketPool();
		Scale2 s1 = new Scale2("wang", t);
		Scale2 s2 = new Scale2("...", t);
		s1.start();
		s2.start();
	}
}


// 同步代码块测试
class Saler extends Thread {
	// 新建线程锁
	static Object lock = new Object();
	private String name;
	private static int ticketNum = 100;


	public Saler(String name) {
		this.name = name;
	}


	public void run() {
		while (ticketNum > 0) {
			// 被锁住的代码,同一时间只有一个分线程在执行
			int num = ticketNum;
			synchronized (lock) {
				ticketNum = ticketNum - 1;
			}
			System.out.println(name + "买票" + num);
		}
	}
}


// 同步静态方法测试
class Saler1 extends Thread {
	private String name;
	private static int ticketNum = 100;


	public Saler1(String name) {
		this.name = name;
	}


	public void run() {
		while (ticketNum > 0) {
			int num = showTicket();
			System.out.println(name + "买票" + num);
		}
	}


	// 同步方法
	public static synchronized int showTicket() {
		int num = ticketNum;
		ticketNum = ticketNum - 1;
		return num;
	}
}


// 同步非静态方法
// 抽取多个线程会共用的资源
class TicketPool {
	public int num = 100;


	public synchronized int showTicket() {
		return num--;
	}
}


class Scale2 extends Thread {
	private String name;
	private TicketPool tkPool;


	public Scale2(String name, TicketPool tkPool) {
		this.name = name;
		this.tkPool = tkPool;
	}


	public void run() {
		while (tkPool.num > 0) {
			int num = tkPool.showTicket();
			System.out.println(name + "买票" + num);
		}
	}
}


Part3、 练习
------------------------
    1.过山洞
        5辆汽车过山洞,每次只允许一辆汽车通过,每辆汽车通过时间不同(2,5,7,9,10),设计程序,完成汽车通过山洞的场景。
        提示:汽车是线程。
        使用同步代码块和同步方法两种方式实现。

    2.银行存钱取票机的问题.
        50人去银行存钱,从取票机取票号问题。每个人取得票号是唯一的。
        使用同步代码块和同步方法两种方式实现。


Part3代码展示
public class Ts02 {


	public static void main(String[] args) {
		// Car c1 = new Car("111", 2000);
		// Car c2 = new Car("222", 4000);
		// Car c3 = new Car("333", 6000);
		// c1.start();
		// c2.start();
		// c3.start();
		BankTicketPool t = new BankTicketPool();
		for (int i = 0; i < 50; i++) {
			Person p = new Person(i, t);
			p.start();
		}
	}
}


// 过山洞
// ------------------------------------
class Cave {
	// 同步方法
	public synchronized void throught(Car car) {
		System.out.println(car.name + "汽车正在通过山洞...");
	}
}


class Car extends Thread {
	public static Cave cave = new Cave();
	public String name;
	public int time;
	static Object lock = new Object();


	public Car(String name, int time) {
		this.name = name;
		this.time = time;
	}


	// 同步代码块
	public void run() {
		// synchronized (lock) {
		//
		// System.out.println(name + "汽车正在通过山洞...");
		// try
		// {
		// Thread.sleep(time);
		// }
		// catch (Exception e)
		// {
		//
		// }
		// }
		through(name, time);
	}


	// 同步方法
	public static synchronized void through(String name, int time) {
		System.out.println(name + "汽车正在通过山洞...");
		try {
			Thread.sleep(time);
		} catch (Exception e) {
		}
	}
}


// 银行排号码
// ------------------------------------
class BankTicketPool {
	int tickNum = 100;


	public synchronized int showTick() {
		return tickNum++;
	}
}


class Person extends Thread {
	int id;
	BankTicketPool tp;


	public Person(int id, BankTicketPool tp) {
		this.id = id;
		this.tp = tp;
	}


	public void run() {
		int num = tp.showTick();
		System.out.println(id + "取到的号码是" + num);
	}
}



全文完!




猜你喜欢

转载自blog.csdn.net/xcvbxv01/article/details/80849845
今日推荐