有时候我们并不想在整个方法前面加上synchronized这个关键字,这样会使整个方法调用变的缓慢,我们只在关键
代码的地方增加这个synchronized这个关键字,然后这样就能加快方法或者代码的执行效率。然后可能还有一种情况就
是,我们有两个变量,其中任何一个变量都是同时只能一个变量访问,但是两个变量可以在同时被两个变量访问,这种
需求下我们就得使用sychronized的带参数的方法来实现这种需求。
下面我们来看一个例子,一个模拟电影院售票的例子
package com.bird.concursey.charpet2;
public class Cinema {
private long vacanciesCinema1;
private long vacanciesCinema2;
private final Object controlCinema1 = new Object();
private final Object controlCinema2 = new Object();
public Cinema() {
vacanciesCinema1 = 20;
vacanciesCinema2 = 20;
}
public boolean sellTickets1(int number) {
synchronized (controlCinema1) {
if(number < vacanciesCinema1) {
vacanciesCinema1 -= number;
return true;
}else{
return false;
}
}
}
public boolean sellTickets2(int number) {
synchronized (controlCinema2) {
if(number < vacanciesCinema2) {
vacanciesCinema2 -= number;
return true;
}else{
return false;
}
}
}
public boolean returnTicket1(int number) {
synchronized (controlCinema1) {
vacanciesCinema1 += number;
return true;
}
}
public boolean returnTicket2(int number) {
synchronized (controlCinema2) {
vacanciesCinema2 += number;
return true;
}
}
public long getVacanciesCinema1() {
return vacanciesCinema1;
}
public void setVacanciesCinema1(long vacanciesCinema1) {
this.vacanciesCinema1 = vacanciesCinema1;
}
public long getVacanciesCinema2() {
return vacanciesCinema2;
}
public void setVacanciesCinema2(long vacanciesCinema2) {
this.vacanciesCinema2 = vacanciesCinema2;
}
}
下面是实际售票的类
package com.bird.concursey.charpet2;
public class TicketOffice1 implements Runnable {
private Cinema cinema;
public TicketOffice1(Cinema cinema) {
this.cinema = cinema;
}
@Override
public void run() {
cinema.sellTickets1(3);
cinema.sellTickets1(2);
cinema.sellTickets2(2);
cinema.returnTicket1(3);
cinema.sellTickets1(5);
cinema.sellTickets2(2);
cinema.sellTickets2(2);
cinema.sellTickets2(2);
}
}
package com.bird.concursey.charpet2;
public class TicketOffice2 implements Runnable {
private Cinema cinema;
public TicketOffice2(Cinema cinema) {
this.cinema = cinema;
}
@Override
public void run() {
cinema.sellTickets2(2);
cinema.sellTickets2(4);
cinema.sellTickets1(2);
cinema.sellTickets1(1);
cinema.returnTicket2(2);
cinema.sellTickets1(3);
cinema.sellTickets2(2);
cinema.sellTickets1(2);
}
public static void main(String[] args) {
Cinema cinema = new Cinema();
TicketOffice1 ticketOffice1 = new TicketOffice1(cinema);
Thread thread1 = new Thread(ticketOffice1, "TicketOffice1");
TicketOffice2 ticketOffice2 = new TicketOffice2(cinema);
Thread thread2 = new Thread(ticketOffice2, "TicketOffice2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Room 1 Vacancies: %d\n",cinema.getVacanciesCinema1());
System.out.printf("Room 2 Vacancies: %d\n",cinema.getVacanciesCinema2());
}
}
这里可以看到,每次运行都会是期望的效果,而且通过单例模式,我们很好的控制了两个属性的访问顺序,很好的实
现了我们的需求。