首页 > 代码库 > Java并发学习之十二——在同步的类里安排独立属性

Java并发学习之十二——在同步的类里安排独立属性

本文是学习网络上的文章时的总结,感谢大家无私的分享。

当你使用synchronized关键字来保护代码块时,你必须通过一个对象的引用作为参数。通常,你将会使用this关键字来引用执行该方法的对象,但是你也可以使用其他对象引用。通常情况下,这些对象被创建只有这个目的。比如,你在一个类中有被多个线程共享的两个独立属性。你必须同步访问每个变量,如果有一个线程访问一个属性和另一个线程在同一时刻访问另一个属性,这是没有问题的。

当你使用synchronized关键字来保护代码块,你使用一个对象作为参数。JVM可以保证只有一个线程可以访问那个对象保护所有的代码块(请注意,我们总是谈论的对象,而不是类)。

package chapter2;

public class Cinema {
	private long vacanciesCinema1;
	private long vacanciesCinema2;
	private final Object controlCinema1,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 sellTickets2(int number) {
		synchronized (controlCinema2) {
			if(number < vacanciesCinema2){
				vacanciesCinema2 -=number;
				return true;
			}else{
				return false;
			}
		}
	}

	public boolean returnTickets1(int number){
		synchronized (controlCinema1) {
			vacanciesCinema1 +=number;
			return true;
		}
	}
	public boolean returnTickets2(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 chapter2;

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.returnTickets1(3);
		cinema.sellTickets1(5);
		cinema.sellTickets2(2);
		cinema.sellTickets2(2);
		cinema.sellTickets2(2);
		
	}
}

package chapter2;

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.returnTickets2(2);
		cinema.sellTickets1(3);
		cinema.sellTickets2(2);
		cinema.sellTickets1(2);
		
	}
}

package chapter2;

public class Main3 {
	/**
	 * 
	 * <p>
	 * </p>
	 * @author zhangjunshuai
	 * @date 2014-9-15 下午4:52:12
	 * @param args
	 */
	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 (Exception e) {
			e.printStackTrace();
		}
		System.out.printf("Room 1 Vacancies: %d\n",cinema.getVacanciesCinema1());
		System.out.printf("Room 2 Vacancies: %d\n",cinema.getVacanciesCinema2());
	}
}


Java并发学习之十二——在同步的类里安排独立属性