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基础】并发的更多相关文章

  1. [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...

  2. java基础——并发1

    一.并发的定义 并发:对于这个概念一直就是没怎么搞懂,就是感觉特别的生疏,(自己从从字面上理解就是多个东西,一起出发),所以就上网上查了一些资料: 同时拥有两个或多个线程,如果程序在单核处理器上运行, ...

  3. Java基础-并发篇

    3.1. JAVA 并发知识库 3.2. JAVA 线程实现/创建方式 3.2.1. 继承 Thread 类 ​ Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例. ...

  4. JAVA基础(9)——容器(3)——并发容器

    转载:http://blog.csdn.net/weitry/article/details/52964509 JAVA基础系列规划: JAVA基础(1)——基本概念 JAVA基础(2)——数据类型 ...

  5. 图学java基础篇之并发

    概述 并发处理本身就是编程开发重点之一,同时内容也很繁杂,从底层指令处理到上层应用开发都要涉及,也是最容易出问题的地方.这块知识也是评价一个开发人员水平的重要指标,本人自认为现在也只是学其皮毛,因此本 ...

  6. Java基础之二十 并发

    20.1 并发得多面性 并发编程令人困惑的一个主要原因:使用并发时需要解决的问题有多个,而实现并发的方法也有多种,并且在这两者之间没有明显的映射关系. 20.1.1 更快的执行 速度问题初听起来很简单 ...

  7. Java基础】并发 - 多线程

    Java基础]并发 - 多线程 分类: Java2014-05-03 23:56 275人阅读 评论(0) 收藏 举报 Java   目录(?)[+]   介绍 Java多线程 多线程任务执行 大多数 ...

  8. Java高并发编程基础三大利器之CountDownLatch

    引言 上一篇文章我们介绍了AQS的信号量Semaphore<Java高并发编程基础三大利器之Semaphore>,接下来应该轮到CountDownLatch了. 什么是CountDownL ...

  9. Java基础技术多线程与并发面试【笔记】

    Java基础技术多线程与并发 什么是线程死锁? ​死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去,我们就可以称 ...

  10. 【Java基础】线程和并发机制

    前言 在Java中,线程是一个很关键的名词,也是很高频使用的一种资源.那么它的概念是什么呢,是如何定义的,用法又有哪些呢?为何说Android里只有一个主线程呢,什么是工作线程呢.线程又存在并发,并发 ...

随机推荐

  1. 在Excel中把横行与竖列进行置换、打勾号

    在Excel中把横行与竖列进行置换:复制要置换的单元,在新的单元上右键->选择性复制,会出现对话框,选中“置换”,即可在Excel中打勾号,左手按住ALT不放,右手在小键盘也就是右边的数字键盘依 ...

  2. "SQL Server does not handle comparison of NText, Text, Xml, or Image data types."

    "SQL Server does not handle comparison of NText, Text, Xml, or Image data types." sql2000 ...

  3. 火狐下white-space: nowrap对float的影响

  4. DBImport v3.44 中文版发布:数据库数据互导及文档生成工具(IT人员必备)

    前言: 距离上一个版本V3.3版本的文章发布,已经是1年10个月前的事了. 其实版本一直在更新,但也没什么大的功能更新,总体比较稳定,所以也不怎么写文介绍了. 至于工作上的事,之前有半年时间跑去学英语 ...

  5. SSDB:高性能数据库服务器

    SSDB是一个开源的高性能数据库服务器, 使用Google LevelDB作为存储引擎, 支持T级别的数据, 同时支持类似Redis中的zset和hash等数据结构, 在同时需求高性能和大数据的条件下 ...

  6. 利用SSH Filesystem实现远程文件系统

         远程文件系统的访问有很多种不同的实现方式,一些常见的连接方式比其它特定情况下的更有用.最著名的一个例子就是微软的通用互联网文件系统(CIFS),它可以容许微软Windows"映射网 ...

  7. 使用python拼接多张图片.二三事

    前几日在博客上看到一篇“使用python拼接多张图片”的Blog[具体是能将的图片名字必须是形如xx_1.png ... xx_100.png或者xx_001.png ... xx_100.png,拼 ...

  8. C#设计模式-代理模式

    在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代理对象代替 ...

  9. sql复习第五次

    1.在数据库范围内,关系的每一个属性值是不可分解的 关系中不允许出现重复元组 由于关系是一个集合,因此不考虑元组的顺序 2.笛卡儿积是两个关系的所有元组组合而成的,而等值联接是由笛卡儿积和选择运算组合 ...

  10. WaitType:CXPACKET

    CXPACKET 等待类型是SQL Server 并发执行一个query时产生的.在run一个big query时,SQL Server充分利用系统的所有资源(CPU,Memory,IO),在最短时间 ...