当使用 synchronized 关键字来保护一段代码时,必须传递一个对象引用作为参数。 一般是引用执行此方法的对象(this),但也能用其他的对象引用。一般这些对象将是为此目的而被专门创建。 例如如果您在1个类中有2个独立的属性被多个线程共享,您必须同步对每个变量的访问,但如果一个线程访问一个属性而另一个线程同时访问另一个属性也是没有问题的。
本节的示例代码在 com.elanzone.books.noteeg.chpt2.sect03 package中
数据类 (Cinema)
private long vacanciesCinema1; private long vacanciesCinema2;
private final Object controlCinema1; private final Object controlCinema2;
public Cinema() { controlCinema1 = new Object(); controlCinema2 = new Object(); vacanciesCinema1 = 20; vacanciesCinema2 = 20; }
public boolean sellTickets1(int number) { synchronized (controlCinema1) { if (number < vacanciesCinema1) { vacanciesCinema1 -= number; return true; } else { return false; } } }
public boolean returnTickets1(int number) { synchronized (controlCinema1) { vacanciesCinema1 += number; return true; } }
线程类: 售票厅1 (TicketOffice1)
private Cinema cinema; public TicketOffice1(Cinema cinema) { this.cinema = cinema; }
cinema.sellTickets1(3); cinema.sellTickets1(2); cinema.sellTickets2(2); cinema.returnTickets1(3); cinema.sellTickets1(5); cinema.sellTickets2(2); cinema.sellTickets2(2); cinema.sellTickets2(2);
线程类: 售票厅2 (TicketOffice2)
cinema.sellTickets2(2); cinema.sellTickets2(4); cinema.sellTickets1(2); cinema.sellTickets1(1); cinema.returnTickets2(2); cinema.sellTickets1(3); cinema.sellTickets2(2); cinema.sellTickets1(2);
控制类 (Main)
Cinema cinema = new Cinema();
TicketOffice1 office1 = new TicketOffice1(cinema); Thread thread1 = new Thread(office1, "TicketOffice1"); TicketOffice2 office2 = new TicketOffice2(cinema); Thread thread2 = new Thread(office2, "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());