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());
	}
}
时间: 2024-10-11 07:47:30

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

Java并发学习之十六——线程同步工具之信号量(Semaphores)

本文是学习网络上的文章时的总结,感谢大家无私的分享. 当一个线程想要访问某个共享资源,首先,它必须获得semaphore.如果semaphore的内部计数器的值大于0,那么semaphore减少计数器的值并允许访问共享的资源.计数器的值大于0表示,有可以自由使用的资源,所以线程可以访问并使用它们. package chapter3; import java.util.concurrent.Semaphore; public class PrintQueue2 { private final Se

Java并发学习之十九——线程同步工具之Phaser

本文是学习网络上的文章时的总结.感谢大家无私的分享. JDK 1.7 加入了一个新的工具Phaser.Phaser的在功能上与CountDownLatch有部分重合. 以下使用Phaser类来同步3个并发任务. 这3个任务会在3个不同的目录和它们的子目录中搜索扩展名是.log的文件. 这个任务被分成3个步骤: 1. 在指定的目录和子目录中获得文件扩展名为.log的文件列表. 2. 在操控台打印结果. 在步骤1和步骤2的结尾我们要检查列表是否为空. 假设为空.那么线程直接结束执行并从phaser类

Java并发学习之十八——线程同步工具之CyclicBarrier

本文是学习网络上的文章时的总结,感谢大家无私的分享. CyclicBarrier 类有一个整数初始值,此值表示将在同一点同步的线程数量.当其中一个线程到达确定点,它会调用await() 方法来等待其他线程.当线程调用这个方法,CyclicBarrier阻塞线程进入休眠直到其他线程到达.当最后一个线程调用CyclicBarrier 类的await() 方法,它唤醒所有等待的线程并继续执行它们的任务. 注意比较CountDownLatch和CyclicBarrier: 1.CountDownLatc

Java并发学习之十四——使用Lock同步代码块

本文是学习网络上的文章时的总结,感谢大家无私的分享. Java提供另外的机制用来同步代码块.它比synchronized关键字更加强大.灵活.Lock 接口比synchronized关键字提供更多额外的功能.在使用Lock时需要注意的是要释放Lock锁. package chapter2; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* * 打印队列 */ pu

java jvm学习笔记十二(访问控制器的栈校验机制)

欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们会简单的描述一下jvm访问控制器的栈校验机制. 这节课,我们还是以实践为主,什么是栈校验机制,讲一百遍不如你自己实际的代码一下然后验证一下,下面我们下把环境搭起来. 第一步,配置系统环境.(copy吧,少年) path=%JAVA_HOME%/bin JAVA_HOME=C:/Java/jdk1.6

Java 并发编程(四)常用同步工具类

同步工具类可以使任何一种对象,只要该对象可以根据自身的状态来协调控制线程的控制流.阻塞队列可以作为同步工具类,其他类型的同步工具类还包括:信号量(Semaphore).栅栏(Barrier)以及闭锁(Latch). 闭锁 首先我们来介绍闭锁. 闭锁作用相当于一扇门:在闭锁到达某一状态之前,这扇门一直是关闭的,所有的线程都会在这扇门前等待(阻塞).只有门打开后,所有的线程才会同时继续运行. 闭锁可以用来确保某些活动直到其它活动都完成后才继续执行,例如: 1.确保某个计算在其所有资源都被初始化之后才

Java并发学习之十五——使用读写锁同步数据访问

本文是学习网络上的文章时的总结,感谢大家无私的分享. 读写锁重要的是写锁的使用,只用一个入口. 下面是读写锁使用的例子 package chapter2; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class PricesInfo { private int price1; private int price2;

Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API

不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权限修饰符,默认访问, 类,方法,成员变量 private 权限修饰符,私有访问, 方法,成员变量 static 静态修饰符 方法,成员变量 final 最终修饰符 类,方法,成员变量,局部变量 abstract 抽象修饰符 类 ,方法 我们编写程序时,权限修饰符一般放于所有修饰符之前,不同的权限修饰

Java并发编程(十二):线程池的使用(转载)

本文转载自:http://www.cnblogs.com/dolphin0520/p/3932921.html 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间. 那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务? 在Java中可以通过线程池来达到这样的效果.