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);
}
}
全文完!