基本线程同步(三)在同步的类里安排独立属性

声明:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González     译者:许巧辉  校对:方腾飞

在同步的类里安排独立属性

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

在这个指南中,你将学习如何解决这种情况的一个例子,编程模拟一家电影院有两个屏幕和两个售票处。当一个售票处出售门票,它们用于两个电影院的其中一个,但不能用于两个,所以在每个电影院的免费席位的数量是独立的属性。

准备工作

这个指南的例子使用Eclipse IDE实现。如果你使用Eclipse或其他IDE,如NetBeans,打开它并创建一个新的Java项目。

如何做…

按以下步骤来实现的这个例子:

1.创建一个Cinema类,添加两个long类型的属性,命名为vacanciesCinema1和vacanciesCinema2。

public class Cinema {
private long vacanciesCinema1;
private long vacanciesCinema2;

2.给Cinema类添加两个额外的Object属性,命名为controlCinema1和controlCinema2。

private final Object controlCinema1, controlCinema2;

3.实现Cinema类的构造方法,初始化所有属性。

public Cinema(){
controlCinema1=new Object();
controlCinema2=new Object();
vacanciesCinema1=20;
vacanciesCinema2=20;
}

4.实现sellTickets1()方法,当第一个电影院出售一些门票将调用它。使用controlCinema1对象来控制访问synchronized的代码块。

public boolean sellTickets1 (int number) {
synchronized (controlCinema1) {
if (number<vacanciesCinema1) {
vacanciesCinema1-=number;
return true;
} else {
return false;
}
}
}

5.实现sellTickets2()方法,当第二个电影院出售一些门票将调用它。使用controlCinema2对象来控制访问synchronized的代码块。

public boolean sellTickets2 (int number) {
synchronized (controlCinema2) {
if (number<vacanciesCinema2) {
vacanciesCinema2-=number;
return true;
} else {
return false;
}
}
}

6.实现returnTickets1()方法,当第一个电影院被退回一些票时将调用它。使用controlCinema1对象来控制访问synchronized的代码块。

public boolean returnTickets1 (int number) {
synchronized (controlCinema1) {
vacanciesCinema1+=number;
return true;
}
}

7.实现returnTickets2()方法,当第二个电影院被退回一些票时将调用它。使用controlCinema2对象来控制访问synchronized的代码块。

public boolean returnTickets2 (int number) {
synchronized (controlCinema2) {
vacanciesCinema2+=number;
return true;
}
}

8.实现其他两个方法,用来返回每个电影院空缺位置的数量。

public long getVacanciesCinema1() {
return vacanciesCinema1;
}
public long getVacanciesCinema2() {
return vacanciesCinema2;
}

9.实现TicketOffice1类,并指定它实现Runnable接口。

public class TicketOffice1 implements Runnable {

10.声明一个Cinema对象,并实现该类(类TicketOffice1)的构造器用来初始化这个对象。

private Cinema cinema;
public TicketOffice1 (Cinema cinema) {
this.cinema=cinema;
}

11.实现run()方法,用来模拟在两个电影院的一些操作。

@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);
}

12.实现TicketOffice2类,并指定它实现Runnable接口。

public class TicketOffice2 implements Runnable {

13.声明一个Cinema对象,并实现该类(类TicketOffice2)的构造器用来初始化这个对象。

private Cinema cinema;
public TicketOffice2 (Cinema cinema) {
this.cinema=cinema;
}

14.实现run()方法,用来模拟在两个电影院的一些操作。

@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);
}

15.通过创建类名为Main,且包括main()方法来实现这个示例的主类。

public class Main {
public static void main(String[] args) {

16.声明和创建一个Cinema对象。

Cinema cinema=new Cinema();

17.创建一个TicketOffice1对象,并且用线程来运行它。

TicketOffice1 ticketOffice1=new TicketOffice1(cinema);
Thread thread1=new Thread(ticketOffice1,"TicketOffice1");

18.创建一个TicketOffice2对象,并且用线程来运行它。

TicketOffice2 ticketOffice2=new TicketOffice2(cinema);
Thread thread2=new Thread(ticketOffice2,"TicketOffice2");

19.启动这两个线程。

thread1.start();
thread2.start();

20.等待线程执行完成。

try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

21.两个电影院的空缺数写入控制台。

System.out.printf("Room 1 Vacancies: %d\n",cinema.getVacanciesCinema1());
System.out.printf("Room 2 Vacancies: %d\n",cinema.getVacanciesCinema2());

它是如何工作的…

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

注释:在这个示例中,我们用一个对象来控制vacanciesCinema1属性的访问。所以,在任意时刻,只有一个线程能修改该属性。用另一个对象来控制 vacanciesCinema2属性的访问。所以,在任意时刻,只有一个线程能修改这个属性。但是可能有两个线程同时运行,一个修改 vacancesCinema1属性而另一个修改vacanciesCinema2属性。

当你运行这个示例,你可以看到每个电影院的空缺数量的最后的结果总是预期的。在以下截图中,你可以看到应用程序的执行结果:

3

不止这些…

synchronize关键字还有其他重要用法,请见其他指南中解释这个关键字使用的参见部分。

参见

在第2章,基本线程同步中在同步代码中使用条件的指南。

文章转自 并发编程网-ifeve.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/290564.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

旧项目适配iphone6和iphone plus

iphone手机屏幕大小和像素&#xff1a;1.iPhone5/5s 320x568&#xff0c;像素640x1136&#xff0c;2x2.iPhone6 375x667&#xff0c;像素750x1334&#xff0c;2x3.iPhone6 Plus 414x736&#xff0c;像素1242x2208&#xff0c;3x旧的项目在xcode6上运行在iphone6或…

java之用反射实现方法(已知实体对象和实体参数)

1、问题 有个函数需要在Android 23&#xff08;6.0&#xff09;以上&#xff0c;但是我们的API是22,所以这个实体对象调用不了这个函数&#xff0c;这个时候我们应该想到的是反射&#xff0c;切记。 2、实现 同时看我写得很着急&#xff0c;因为我是先class.forName("**…

Could not load the Tomcat server configuration at \Servers\Tomcat v7.0 Server at localhost-config

之前不小心删除了server的服务器设置&#xff0c;运行时各种报错Could not load the Tomcat server configuration at \Servers\Tomcat v7.0 Server at localhost-config &#xff0c;网上找到解决方法记录下&#xff1a; 第一步&#xff1a;将左边的classpath中的server删除掉…

软件项目组织管理(一)项目管理概述

文章目录什么是项目项目的特征项目的组成要素&#xff08;三维约束&#xff09;什么是项目管理什么是IT项目什么是软件项目管理项目管理的目标&#xff08;项目成功的标志&#xff09;软件项目失败的原因活动的3个基本特点人类活动分为两种类型作业和项目的区别&#xff08;必考…

ABP Framework 5.2 RC 版本发布及新增功能介绍

本文将介绍 ABP Framework 5.2 RC 版新增的主要功能&#xff1a;•单层解决方案模板•API 版本控制•源代码控制移除libs文件夹•对 Swagger UI 隐藏 ABP 默认端点•CMS Kit应用模块自定义全局 CSS 和 JavaScript关注 ABP Framework 最新开发进度&#xff0c;后面还会陆续发布新…

《计算机组成原理》----2.3 二进制运算

本节书摘来自华章出版社《计算机组成原理》一书中的第2章&#xff0c;第2.3节&#xff0c; 作 者 Computer Organization and Architecture: Themes and Variations&#xff3b;英&#xff3d;艾伦克莱门茨&#xff08;Alan Clements&#xff09; 著&#xff0c;沈 立 王苏峰…

JTable常见用法细则

JTable是Swing编程中很常用的控件,这里总结了一些常用方法以备查阅.欢迎补充,转载请注明作者与出处.一.创建表格控件的各种方式:1) 调用无参构造函数. JTable table new JTable();2) 以表头和表数据创建表格. Object[][] cellData {{"row1-col1", "row1-col…

Android之通过ActivityLifecycleCallbacks判断程序是否运行在后台

1、问题 判断程序是否运行在后台运行 2、解决办法 我们可以使用ActivityLifecycleCallbacks,对于ActivityLifecycleCallbacks&#xff0c;看我的这篇博客介绍() Android之ActivityLifecycleCallbacks的得到当前的activity的状态 &#xff08;http://blog.csdn.net/u01106870…

下拉刷新:继承listView控件

1、首先初始化的时候给控件监听OnScrollListener&#xff0c;其中onScroll的参数里得到第一个显示的条目&#xff0c;当第一个条目为0的时候就可以执行下啦刷新了。第二覆写的方法是 onScrollStateChanged就是滑动状态的监听&#xff0c;3种状态都是常量&#xff1a;快速滑动&a…

软件项目组织管理(二、三)项目管理与信息技术环境、项目管理过程组

文章目录系统方法系统管理三维模型组织环境组织的四个框架组织的结构项目生命周期管理评审虚拟团队什么是过程项目管理过程组系统方法 项目管理工作需要采取系统的方法&#xff0c;描述在解决复杂问题时所需的整体性和分析性方法。 系统哲学&#xff1a;将事情作为系统考虑的…

一点杂感 以及 java8 Streams API 与 C# Linq 简要对比分析

写在前面的一点小吐槽、一点杂感学 Haskell 学了一段时间之后&#xff0c;虽说拿他来写东西还是完全不行&#xff0c;但是看别的语言特性时&#xff0c;总是会带着一种“诶&#xff0c;这玩意在哪哪见过”的蜜汁既视感。且不说几乎成为现代编程语言标配的 Lambda 、闭包&#x…

svn之迁移代码技巧

1、问题 之前客户做了很多定制&#xff0c;加起来有10几个&#xff0c;每个项目里面4分代码&#xff0c;需要迁移到高版本里面去。我特么傻逼了看每次svn记录然后一个一个的修改&#xff0c;日了狗一样。 2、解决办法 点击到当前目录 svn showlog 然后 ctrl A 然后点击鼠标右…

《编译与反编译技术》—第1章1.7节C语言程序的编译流程

本节书摘来自华章出版社《编译与反编译技术》一书中的第1章&#xff0c;第1.7节C语言程序的编译流程&#xff0c;作者庞建民&#xff0c;陶红伟&#xff0c;刘晓楠&#xff0c;岳峰&#xff0c;更多章节内容可以访问云栖社区“华章计算机”公众号查看。1.7 C语言程序的编译流程…

Base64

2019独角兽企业重金招聘Python工程师标准>>> Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64&#xff0c;所以每6个比特为一个单元&#xff0c;对应某个可打印字符。三个字节有24个比特&#xff0c;对应于4个Base64单元&#xff0c…

字符编码总结

字符编码精华总结 文件或字符串乱码相信大家都没少遇到, 今天主要就来搞清楚字符串的编码到底是怎 么一回事. 首先, 我们放把自己置空, 假设现在从来没有字符编码, 刚有一台计算机产生, 让我 们来设计一套方案, 目标是让在计算机屏幕上看到我们平时所书写的字符. 你会怎么 做?…

软件配置管理(六)常用配置软件配置工具指令

文章目录软件配置管理工具的主要功能两种版本控制模型Lock-Modify-UnlockCopy-Modify-MergeSubversionGit软件配置管理工具的主要功能 版本控制变更管理配置审核配置状态统计问题跟踪访问控制和安全控制 两种版本控制模型 Lock-Modify-Unlock “加锁-修改-解锁”模型 对于版…

.NET 6 攻略大全(一)

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;15分钟)欢迎使用 .NET 6。今天的版本是.NET 团队和社区一年多努力的结果。C# 10 和 F# 6 提供了语言改进&#xff0c;使您的代码更简单、更好、性能大幅提升&#xff0c;我们已经看到微软降低了托管云服务的成本。.NE…

http和https和ssl和tcp/ip之间的关系和区别

1、http解释 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准,HTTP是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。在Internet上的Web服务器上存放的都是超文本信息,客户机需要通过HT…

Win7下JDK环境变量的设置

JDK并不像Microsoft阵营vs那样智能&#xff0c;安装好后所有的东西都给你配置好了&#xff0c;我们还没需要手动配置很多东西 首先说为什么要配置JDK的环境变量在任何路径下识别java命令和java类 配置分为2个部分&#xff0c;1&#xff0c;java命令路径。2,java加载类 分为3个步…

简单模拟实现简单的当登录延时的效果

①、先建立一个activaty去部署我们的登陆界面 1 package com.example.administrator.actionbardemo;2 3 import android.app.Activity;4 import android.content.Intent;5 import android.os.Bundle;6 import android.view.View;7 import android.widget.Button;8 import andro…