文档章节

【Java并发编程实战】– 使用非依赖属性实现同步

pan_1308
 pan_1308
发布于 2017/09/07 15:01
字数 608
阅读 7
收藏 0
点赞 0
评论 0

一、概述

当使用 synchronized 关键字 来保护代码块时,必须把对象引用作为 传入参数。

通常情况下,使用 this 关键字来引用执行方法所属的对象,也可以使用其他的对象对其进行引用。一般来说,这些对象就是为了这个目的而创建的。

例如,在类中有两个非依赖属性,它们被多个线程共享,你必须同步每一个变量的访问,但是同一时刻 只允许一个线程访问一个属性变量,其他的某个线程访问另外一个属性变量。

二、实现

示例: 模拟实现 电影院售票场景,有2个 屏幕 和 2个售票处的电影院,一个售票处卖出的一张票,只能用于其中的一个电影院,不能同时用于2个电影院,因此每个电影院的剩余票数是独立的属性。

/**
 * 使用非依赖属性实现同步
 * 电影院
 * 模拟电影院售票情景
 */
public class Cinema {
   
	private long vacanciesCinema1;  // 电影院1 的票
	private long vacanciesCinema2;  // 电影院2 的票
	
	// 2个对象属性
	private final Object controlCinema1, controlCinema2;  
	
	public Cinema(){
		controlCinema1 = new Object();  
		controlCinema2 = new Object();
		vacanciesCinema1 = 20;  
		vacanciesCinema2 = 20;
	}
	
	// 第一个电影院卖票  -> 使用 controlCinema1对象来控制同步代码块的访问.
	public boolean sellTickets1(int num){
		synchronized (controlCinema1) {
		   if(vacanciesCinema1 < num){
			   return false;
		   }
		   vacanciesCinema1 -= num;
		   return true;
		}
	}
	
	// 第二个电影院卖票  -> 使用 controlCinema2对象来控制同步代码块的访问.
	public boolean sellTickets2(int num){
		synchronized (controlCinema2) {
		   if(vacanciesCinema2 < num){
			   return false;
		   }
		   vacanciesCinema2 -= num;
		   return true;
		}
	}
	
	//第一个电影院退票
	public boolean returnTickets1(int num){
		synchronized (controlCinema1) {
			vacanciesCinema1 += num;
			return true;
		}
	}
	
	//第二个电影院退票
	public boolean returnTickets2(int num){
		synchronized (controlCinema2) {
			vacanciesCinema2 += num;
			return true;
		}
	}
	
	public long getVacanciesCinema1() {
		return vacanciesCinema1;
	}
	
	public long getVacanciesCinema2() {
		return vacanciesCinema2;
	}
}
/***
 * 售票处1
 */
public class TicketOffice1 implements Runnable{

	private Cinema cinema;
	
	public TicketOffice1(Cinema cinema) {
		this.cinema = cinema;
	}
	
	public void run() {
		cinema.sellTickets1(2);
		cinema.sellTickets1(1);
		cinema.sellTickets2(3);
		cinema.sellTickets2(2);
		cinema.returnTickets1(1);
		cinema.returnTickets2(2);
	}
}
/***
 * 售票处2
 */
public class TicketOffice2 implements Runnable{

	private Cinema cinema;
	
	public TicketOffice2(Cinema cinema){
		this.cinema = cinema;
	}
	
	@Override
	public void run() {
		cinema.sellTickets1(1);
		cinema.sellTickets2(2);
		cinema.sellTickets1(5);
		cinema.sellTickets1(3);
		cinema.sellTickets2(4);
		cinema.returnTickets1(2);
		cinema.returnTickets2(1);
	}

}
/**
 * 测试
 */
public class CinemaTest {

	public static void main(String[] args) {
		Cinema cinema = new Cinema();
		TicketOffice1 ticketOffice1 = new TicketOffice1(cinema);
		TicketOffice2 ticketOffice2 = new TicketOffice2(cinema);
		
		Thread thread1 = new Thread(ticketOffice1);
		Thread thread2 = new Thread(ticketOffice2);
		
		thread1.start();
		thread2.start();
		
		try {
			thread1.join();
			thread2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.err.println("电影院1 剩余:" + cinema.getVacanciesCinema1());
		System.err.println("电影院2 剩余:" + cinema.getVacanciesCinema2());
	}
	
}


//console结果:
电影院1 剩余:11
电影院2 剩余:12

 

 

© 著作权归作者所有

共有 人打赏支持
pan_1308
粉丝 4
博文 84
码字总数 58819
作品 0
黄冈
Java多线程学习(二)synchronized关键字(2)

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀 ⋅ 04/16 ⋅ 0

【Java并发专题】27篇文章详细总结Java并发基础知识

努力的意义,就是,在以后的日子里,放眼望去全是自己喜欢的人和事! github:https://github.com/CL0610/Java-concurrency,欢迎题issue和Pull request。所有的文档都是自己亲自码的,如果觉...

你听___ ⋅ 05/06 ⋅ 0

Java 5 、6、 7中新特性

JDK5新特性(与1.4相比)【转】 1 循环 for (type variable : array){ body} for (type variable : arrayList){body} 而1.4必须是: for (int i = 0; i < array.length; i++){ type variabl......

thinkyoung ⋅ 2014/10/14 ⋅ 0

计算机科学中抽象的好处与问题—伪共享实例分析

David John Wheeler有一句名言“计算机科学中的任何问题都可以通过加上一层间接层来解决”,一层不够就再加一层。后半句是我加的 (* ̄︶ ̄) ,虽然有点玩笑的意思,但是也的确能说明一些问题...

MageekChiu ⋅ 01/10 ⋅ 0

Java并发基础你需要知道的基础知识

多线程和并发编程是Java里面的核心内容,通常有以下一些概念需要重点掌握。 线程; 锁; 同步器; 并发容器和框架; Java并发工具类; 原子操作类; Executor框架(执行机制); 并发基础概念 ...

异步社区 ⋅ 05/30 ⋅ 0

Java 编程之美:并发编程基础晋级篇

本文来自作者 加多 在 GitChat 上分享 「Java 并发编程之美:并发编程基础晋级篇」 编辑 | Mc Jin 借用 Java 并发编程实践中的话,编写正确的程序并不容易,而编写正常的并发程序就更难了! ...

gitchat ⋅ 04/18 ⋅ 0

书单丨5本Java后端技术书指引你快速进阶

一名Java开发工程师 不仅要对Java语言及特性有深层次的理解 而且需要掌握与Java相关的 框架、生态及后端开发知识 本文涉及多种后端开发需要掌握的技能 对于帮助提高开发能力非常有帮助 NO.1...

Java高级架构 ⋅ 05/30 ⋅ 0

[Java 并发编程] 集合框架之 同步容器类 & 并发容器类

吾生也有涯,而知也无涯。———《庄子》 通过上一篇文章,我们已经知道设计一个线程安全类的原则和步骤,以及在设计过程中我们应当注意的细节。实际上,Java 的集合库包含了线程安全集合和非...

seaicelin ⋅ 05/25 ⋅ 0

悲观的并发策略——synchronized互斥锁

互斥锁是最常见的同步手段,在并发过程中,当多条线程对同一个共享数据竞争时,它保证共享数据同一时刻只能被一条线程使用,其他线程只有等到锁释放后才能重新进行竞争。 对于Java开发人员,...

wangyangzhizhou ⋅ 04/16 ⋅ 0

多线程基础必要知识点!看了学习多线程事半功倍

前言 不小心就鸽了几天没有更新了,这个星期回家咯。在学校的日子要努力一点才行! 只有光头才能变强 回顾前面: 多线程三分钟就可以入个门了! Thread源码剖析 本文章的知识主要参考《Java并...

Java3y ⋅ 04/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL主从复制原理、半同步操作步骤及原理

1.1 企业Linux运维场景数据同步方案 1.1.1 文件级别的异机同步方案 1、scp/sftp/nc 命令可以实现远程数据同步。 2、搭建ftp/http/svn/nfs 服务器,然后在客户端上也可以把数据同步到服务器。...

xiaomin0322 ⋅ 11分钟前 ⋅ 0

Oracle10g 数据及文件迁移过程[原]

QL*Plus: Release 10.2.0.1.0 - Production on 星期三 5月 11 10:22:35 2011 Copyright (c) 1982, 2005, Oracle. All rights reserved. 连接到: Oracle Database 10g Enterprise Edition Re......

harrypotter ⋅ 17分钟前 ⋅ 0

nginx安装

1:安装工具包 wget、vim和gcc yum install -y wget yum install -y vim-enhanced yum install -y make cmake gcc gcc-c++ 2:下载nginx安装包 wget http://nginx.org/download/nginx-1......

壹丶贰 ⋅ 20分钟前 ⋅ 0

ideaVim安装及配置

1.安装插件 File-Settings-Plugins,Browse Repositories,输入ideavim,安装。 重启后,在Tools-Vim Emulator启用。 2.快捷键设置 ideaViim键与idea快捷键有冲突,可以在Settings-Other Se...

Funcy1122 ⋅ 24分钟前 ⋅ 0

MySQL中B+Tree索引原理

B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。B+树中的B代表平衡(balance),而不是二叉(binary),因为B+树是从最早的平衡二叉树演化而来的。在讲B...

浮躁的码农 ⋅ 39分钟前 ⋅ 0

两道面试题,带你解析Java类加载机制

在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题: class Grandpa{ static { System.out.println("爷爷在静态代码块"); }} cl...

1527 ⋅ 43分钟前 ⋅ 0

SpringCloud(Data Flow)

dataflow-server

赵-猛 ⋅ 53分钟前 ⋅ 0

深入理解Java虚拟机

这本书我读到第8章,之后就是在读不下去了。 读到后面是一种痛苦的体验,太多的东西是不全面的,大量的专有名词是没有解释的,读到最后很多东西仅仅是一个侧面,所以我觉得,这本书不适合初学...

颖伙虫 ⋅ 58分钟前 ⋅ 0

NanoPi NEO core/ Ubuntu16.04单网卡配置3个IP地址(2个静态,1个动态)

配置 root@NanoPi-NEO-Core:/etc/network# cat interfacesauto loiface lo inet loopbackallow-hotplug eth0iface eth0 inet static address 172.31.188.249 netmask 255.......

SamXIAO ⋅ 今天 ⋅ 0

三步为你的App集成LivePhoto功能

摘要:LivePhoto是iOS9新推出的一种拍照方式,类似于拍摄Gif图或录制视频片段生成图片。如果没有画面感,可以联想《哈利波特》霍格沃茨城堡的壁画,哈哈,很炫酷有木有,但坑爹的是只有iphone6S以...

壹峰 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部