【Java基础】并发
Num1:同步访问共享的可变数据
关键字Synchronized可以保证在同一时刻,只有一个线程可以执行某一个方法,或者某一个代码块。、
同步不仅仅理解为互斥的方式,如果没有同步,一个线程的变化就不能被其他线程看到。同步不仅可以阻止一个线程看到对象处于不一致的状态中,它还可以保证进入同步方法或者同步代码块的每个线程,都看到由同一个锁保护之前的所有修改效果。
基本版本:
public class StopThread {
private static boolean stopRequested;
private static synchronized void requestStop() {
stopRequested = true;
}
private static synchronized boolean stopRequested() {
return stopRequested;
}
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!stopRequested())
i++;
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
改善版本:
public class StopThread {
private static volatile boolean stopRequested;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!stopRequested)
i++;
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
简而言之,当多个线程共享可变数据的时候,每个读或者写数据的线程都必须执行同步。如果没有同步,就无法保证一个线程所做的修改可以被另一个线程获知,未能同步共享可变的数据或造成程序的活性失败和安全性失败。
Num2:executor和task优先于线程
如何创建一个工作队列呢,一行代码。
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(runnable);
executor.shutdown();
如果想让不止一个线程来处理来自这个队列的请求,只要调用一个不同的静态工厂,这个工厂创建了一种不同的executor service,称作线程池(thread pool)。
Num3:慎用延迟初始化
延迟初始化是延迟到需要域的是值时才将它初始化的这种行为。如果永远不需要这个值,这个域就永远不会被初始化。这种方法既适用于静态域,也适用于实例域。虽然延迟初始化主要是一种优化,但它也可以用来打破类和实例初始化的有害循环。
在大多数情况下,正常的初始化要优先于延迟初始化。
如果利用延迟优化来破坏初始化的循环,就要使用同步的访问方法。
如果出于性能的考虑而需要对静态域使用延迟初始化,就用
lazy initialization holder class模式。如果出于性能的考虑而需要对实例域使用延迟初始化,就用双重检查模式
double-check idiom。单重检查模式
single-check idiom。
示例代码:
public class Initialization {
// Normal initialization of an instance field - Page 282
private final FieldType field1 = computeFieldValue();
// Lazy initialization of instance field - synchronized accessor - Page 282
private FieldType field2;
synchronized FieldType getField2() {
if (field2 == null)
field2 = computeFieldValue();
return field2;
}
// Lazy initialization holder class idiom for static fields - Page 283
private static class FieldHolder {
static final FieldType field = computeFieldValue();
}
static FieldType getField3() {
return FieldHolder.field;
}
// Double-check idiom for lazy initialization of instance fields - Page 283
private volatile FieldType field4;
FieldType getField4() {
FieldType result = field4;
if (result == null) { // First check (no locking)
synchronized (this) {
result = field4;
if (result == null) // Second check (with locking)
field4 = result = computeFieldValue();
}
}
return result;
}
// Single-check idiom - can cause repeated initialization! - Page 284
private volatile FieldType field5;
private FieldType getField5() {
FieldType result = field5;
if (result == null)
field5 = result = computeFieldValue();
return result;
}
private static FieldType computeFieldValue() {
return new FieldType();
}
}
class FieldType {
}
【Java基础】并发的更多相关文章
- [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...
- java基础——并发1
一.并发的定义 并发:对于这个概念一直就是没怎么搞懂,就是感觉特别的生疏,(自己从从字面上理解就是多个东西,一起出发),所以就上网上查了一些资料: 同时拥有两个或多个线程,如果程序在单核处理器上运行, ...
- Java基础-并发篇
3.1. JAVA 并发知识库 3.2. JAVA 线程实现/创建方式 3.2.1. 继承 Thread 类 Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例. ...
- JAVA基础(9)——容器(3)——并发容器
转载:http://blog.csdn.net/weitry/article/details/52964509 JAVA基础系列规划: JAVA基础(1)——基本概念 JAVA基础(2)——数据类型 ...
- 图学java基础篇之并发
概述 并发处理本身就是编程开发重点之一,同时内容也很繁杂,从底层指令处理到上层应用开发都要涉及,也是最容易出问题的地方.这块知识也是评价一个开发人员水平的重要指标,本人自认为现在也只是学其皮毛,因此本 ...
- Java基础之二十 并发
20.1 并发得多面性 并发编程令人困惑的一个主要原因:使用并发时需要解决的问题有多个,而实现并发的方法也有多种,并且在这两者之间没有明显的映射关系. 20.1.1 更快的执行 速度问题初听起来很简单 ...
- Java基础】并发 - 多线程
Java基础]并发 - 多线程 分类: Java2014-05-03 23:56 275人阅读 评论(0) 收藏 举报 Java 目录(?)[+] 介绍 Java多线程 多线程任务执行 大多数 ...
- Java高并发编程基础三大利器之CountDownLatch
引言 上一篇文章我们介绍了AQS的信号量Semaphore<Java高并发编程基础三大利器之Semaphore>,接下来应该轮到CountDownLatch了. 什么是CountDownL ...
- Java基础技术多线程与并发面试【笔记】
Java基础技术多线程与并发 什么是线程死锁? 死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去,我们就可以称 ...
- 【Java基础】线程和并发机制
前言 在Java中,线程是一个很关键的名词,也是很高频使用的一种资源.那么它的概念是什么呢,是如何定义的,用法又有哪些呢?为何说Android里只有一个主线程呢,什么是工作线程呢.线程又存在并发,并发 ...
随机推荐
- 爬虫初探(2)之requests
关于请求网络,requests这个库是爬虫经常用到的一个第三方库. import requests url = 'http://www.baidu.com' #这里用get方法用来请求网页,其他还有p ...
- js 获取浏览器高度和宽度值(多浏览器)(转)
IE中: document.body.clientWidth ==> BODY对象宽度 document.body.clientHeight ==> BODY对象高度 document.d ...
- DevOps是云计算时代的开发与运营
DevOps(英文Development和Operations的组合)是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与整合.[1] 它 ...
- 标准数据源访问库 - JayData
JayData 是一个标准的.跨平台的库和方法,用于访问和操作各种不同的数据源,最适合用于 JavaScript 和 HTML5 应用. 官方网站:http://jaydata.org/ ASP.N ...
- quick-cocos2d-x 2.2.3 rc版本中 crypto.md5file() 的C++实现在ANDROID上有BUG
原来的版本是用fopen打开文件的,如果要从ANDROID的APK中取文件,直接就洗白了修改如下 void CCCrypto::MD5File(const char* path, unsigned c ...
- CI框架搭建
CI 框架等移植到不同等环境十分方便,只要改很少等配置: 1.修改config.php 文件(修改这一个文件就可以跑通了): $config['base_url'] = 'http://127.0.0 ...
- Underscore.js使用
Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象. 他解决了这个问题:"如果我面对一个空白的 ...
- Atitit 设计模式与算法,与流程的关系
Atitit 设计模式与算法,与流程的关系 1.1. 设计模式就是算法 就是流程,不同的方面看法不同,抽象方法不同而造成的假象. 软件就是由设计模式累积成的.也可以说算法累计成的.. ,而可以用Vis ...
- js创建对象的高级模式
hello,安瑞万.第一次写博客,心情很激动啊.要是说的不好,你来打我啊?反正你也不知道我家地址.好了,不扯了.进入正题:要是写的不好欢迎大家来批评指导. what:创建对象的三种模式 --1,门户大 ...
- WCF学习之旅——第一个WCF示例(一)
最近需要用到WCF,所以对WCF进行了解.在实践中学习新知识是最快的,接下来先做了一个简单的WCF服用应用示例. 本文的WCF服务应用功能很简单,却涵盖了一个完整WCF应用的基本结构.希望本文能对那些 ...