当前位置: 首页 > news >正文

摄影网站建设目的app网站开发书籍下载

摄影网站建设目的,app网站开发书籍下载,池州做网站的公司,大连网站制作姚喜运在回顾了处理并发程序时的主要风险#xff08;如原子性或可见性 #xff09;之后#xff0c;我们将进行一些类设计#xff0c;以帮助我们防止上述错误。 其中一些设计导致了线程安全对象的构造#xff0c;从而使我们可以在线程之间安全地共享它们。 作为示例#xff0c;我… 在回顾了处理并发程序时的主要风险如原子性或可见性 之后我们将进行一些类设计以帮助我们防止上述错误。 其中一些设计导致了线程安全对象的构造从而使我们可以在线程之间安全地共享它们。 作为示例我们将考虑不可变和无状态的对象。 其他设计将阻止不同的线程修改相同的数据例如线程局部变量。 您可以在github上查看所有源代码。 1.不可变的对象 不可变的对象具有状态具有表示对象状态的数据但是它是基于构造构建的一旦实例化了对象就无法修改状态。 尽管线程可以交错但是对象只有一种可能的状态。 由于所有字段都是只读的因此没有一个线程可以更改对象的数据。 因此不可变对象本质上是线程安全的。 产品显示了一个不变类的示例。 它在构建期间构建所有数据并且其任何字段均不可修改 public final class Product {private final String id;private final String name;private final double price;public Product(String id, String name, double price) {this.id id;this.name name;this.price price;}public String getId() {return this.id;}public String getName() {return this.name;}public double getPrice() {return this.price;}public String toString() {return new StringBuilder(this.id).append(-).append(this.name).append( ().append(this.price).append()).toString();}public boolean equals(Object x) {if (this x) return true;if (x null) return false;if (this.getClass() ! x.getClass()) return false;Product that (Product) x;if (!this.id.equals(that.id)) return false;if (!this.name.equals(that.name)) return false;if (this.price ! that.price) return false;return true;}public int hashCode() {int hash 17;hash 31 * hash this.getId().hashCode();hash 31 * hash this.getName().hashCode();hash 31 * hash ((Double) this.getPrice()).hashCode();return hash;} } 在某些情况下将字段定为最终值还不够。 例如尽管所有字段都是最终的但MutableProduct类不是不可变的 public final class MutableProduct {private final String id;private final String name;private final double price;private final ListString categories new ArrayList();public MutableProduct(String id, String name, double price) {this.id id;this.name name;this.price price;this.categories.add(A);this.categories.add(B);this.categories.add(C);}public String getId() {return this.id;}public String getName() {return this.name;}public double getPrice() {return this.price;}public ListString getCategories() {return this.categories;}public ListString getCategoriesUnmodifiable() {return Collections.unmodifiableList(categories);}public String toString() {return new StringBuilder(this.id).append(-).append(this.name).append( ().append(this.price).append()).toString();} } 为什么以上类别不是一成不变的 原因是我们让引用脱离了其类的范围。 字段“ category ”是一个可变的引用因此在返回它之后客户端可以对其进行修改。 为了显示此请考虑以下程序 public static void main(String[] args) {MutableProduct p new MutableProduct(1, a product, 43.00);System.out.println(Product categories);for (String c : p.getCategories()) System.out.println(c);p.getCategories().remove(0);System.out.println(\nModified Product categories);for (String c : p.getCategories()) System.out.println(c); } 和控制台输出 Product categoriesABCModified Product categoriesBC 由于类别字段是可变的并且逃脱了对象的范围因此客户端已修改类别列表。 该产品原本是一成不变的但已经过修改从而进入了新的状态。 如果要公开列表的内容可以使用列表的不可修改视图 public ListString getCategoriesUnmodifiable() {return Collections.unmodifiableList(categories); }2.无状态对象 无状态对象类似于不可变对象但是在这种情况下它们没有状态甚至没有一个状态。 当对象是无状态的时它不必记住两次调用之间的任何数据。 由于没有修改状态因此一个线程将无法影响另一线程调用对象操作的结果。 因此无状态类本质上是线程安全的。 ProductHandler是此类对象的示例。 它包含对Product对象的多项操作并且在两次调用之间不存储任何数据。 操作的结果不取决于先前的调用或任何存储的数据 public class ProductHandler {private static final int DISCOUNT 90;public Product applyDiscount(Product p) {double finalPrice p.getPrice() * DISCOUNT / 100;return new Product(p.getId(), p.getName(), finalPrice);}public double sumCart(ListProduct cart) {double total 0.0;for (Product p : cart.toArray(new Product[0])) total p.getPrice();return total;} } 在其sumCart方法所述ProductHandler产品列表转换成一个阵列因为for-each循环通过它的元件使用的迭代器内部进行迭代。 列表迭代器不是线程安全的如果在迭代过程中进行了修改则可能引发ConcurrentModificationException 。 根据您的需求您可以选择其他策略 。 3.线程局部变量 线程局部变量是在线程范围内定义的那些变量。 没有其他线程会看到或修改它们。 第一种是局部变量。 在下面的示例中 total变量存储在线程的堆栈中 public double sumCart(ListProduct cart) {double total 0.0;for (Product p : cart.toArray(new Product[0])) total p.getPrice();return total; } 只要考虑一下如果您定义引用并返回它而不是原始类型它将逃避其范围。 您可能不知道返回的引用存储在哪里。 调用sumCart方法的代码可以将其存储在静态字段中并允许在不同线程之间共享。 第二种类型是ThreadLocal类。 此类为每个线程提供独立的存储。 可以从同一线程内的任何代码访问存储在ThreadLocal实例中的值。 ClientRequestId类显示ThreadLocal用法的示例 public class ClientRequestId {private static final ThreadLocalString id new ThreadLocalString() {Overrideprotected String initialValue() {return UUID.randomUUID().toString();}};public static String get() {return id.get();} } ProductHandlerThreadLocal类使用ClientRequestId在同一线程中返回相同的生成ID public class ProductHandlerThreadLocal {//Same methods as in ProductHandler classpublic String generateOrderId() {return ClientRequestId.get();} } 如果执行main方法则控制台输出将为每个线程显示不同的ID。 举个例子 T1 - 23dccaa2-8f34-43ec-bbfa-01cec5df3258T2 - 936d0d9d-b507-46c0-a264-4b51ac3f527dT2 - 936d0d9d-b507-46c0-a264-4b51ac3f527dT3 - 126b8359-3bcc-46b9-859a-d305aff22c7e... 如果要使用ThreadLocal则应注意在线程池化时例如在应用程序服务器中使用它的一些风险。 您可能最终在请求之间出现内存泄漏或信息泄漏。 自从“ 如何与ThreadLocals一起开枪自杀”一文很好地解释了这种情况的发生之后我将不再扩展本主题。 4.使用同步 提供对对象的线程安全访问的另一种方法是通过同步。 如果我们将对引用的所有访问同步则在给定时间只有一个线程将访问它。 我们将在后续帖子中对此进行讨论。 5.结论 我们已经看到了几种技术可以帮助我们构建可以在线程之间安全共享的更简单的对象。 如果一个对象可以具有多个状态则防止并发错误要困难得多。 另一方面如果一个对象只能有一个状态或没有状态则不必担心不同的线程同时访问它。 翻译自: https://www.javacodegeeks.com/2014/08/java-concurrency-tutorial-thread-safe-designs.html
http://www.yutouwan.com/news/272786/

相关文章:

  • 苏州企业网站建设开发与制作太原这边有做网站的吗
  • 创建好网站如何把浏览17zwd一起做网站普宁
  • 高邮市建设局网站株洲县建设局官方网站
  • 帮别人做网站建站公司最喜欢的网站
  • 周口网站建设73data管理系统中计算机应用实践考试
  • 中煤建设集团网站营销型网站建设推荐
  • wordpress 安装502杭州seo代理公司
  • 友情链接的网站阿里云虚拟主机做企业网站
  • 做服装团购有哪些网站有哪些WordPress好用的主题推荐
  • 椒江网站建设578做网站wordpress 文字框
  • 昆明网站设计都需要设计什么网站建设教学课件
  • 做网站买空间用共享ipwordpress快速开发
  • jsp网站开发分享网站企业员工培训内容及计划
  • 住房与城乡建设网站seo优化师
  • 广州市研发网站建设平台网店推广是什么
  • 网站界面设计要素化工行业网站设计
  • 陕西网站建设维护wordpress博客自媒体资讯主题
  • 中国做乱的小说网站wordpress写文章报错
  • 贵州网站推广jp域名
  • 用百度云服务器做网站我常用的网站有哪些类型有哪些类型有哪些
  • 陕西建设网官网三类人员小红书笔记关键词排名优化
  • 长安做网站价格石家庄现状
  • 网站开发主要内容和要求视频转网址在线生成
  • 网站建设规划方案制作做家电选招标采购哪一个网站好
  • 做网站要求付全款网站开发人员调试
  • 郑州影楼网站建设网站要怎么盈利
  • 怎样才能建设只是于自己的网站广东seo推广软件
  • 网站建设短期培训网页微信客户端下载
  • 个人网站 平台免费生成logo的软件
  • 镇江网站设计做薪酬调查的网站