effect java 学习摘要(8) - 并发
2017-08-17 23:54
489 查看
同步访问共享的可变数据
synchronized : 可以保证在同一时刻,只有一个线程可以执行某一个方法, 或者某一个代码块.多线程访问, 可能会导致同一对象状态发生变化. 同步 可以使多线程看到由同一个锁保护的之前所有的修改效果.
非long或double类型的变量, 读写操作一个变量是原子的
在线程之间进行可靠的通信, 也为了互斥访问, 同步是必要的.
不要使用 Thread.stop() , 要阻止一个线程妨碍另一个线程 ,正确做法如下 :
public class StopThread { public static boolean stopRequested; private static synchronized void requestStop() { stopRequested = true; } public static synchronized boolean stopRequested() { return stopRequested; } public void stopThread() throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { int i = 0; while (!stopRequested()) { i++; } } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); requestStop(); } }
如果读写操作都没有进行同步 , 那么同步就不会起作用.
public class StopThread { public static volatile boolean stopRequested; public void stopThread() throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { int i = 0; while (!stopRequested) { i++; } } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); stopRequested = true; } }
多个线程共享可变数据的时候, 每个读或者写数据的线程都必须执行同步
避免过度同步
共享数据类型,需要使用线程安全的数据结构 , 例如 : CopyOnWriteArrayListexecutor和task优先于线程
尽量避免自己编写工作队列, 尽量不要直接使用线程, 使用java提供的executor线程池并发工具优先于wait和notify
线程高级工具 :Executor Framework
并发集合
同步器 : CountDownLatch 和 Semaphore
public class Synchronizer { final Executor executor = Executors.newSingleThreadExecutor(); final CountDownLatch ready = new CountDownLatch(3); final CountDownLatch start = new CountDownLatch(1); final CountDownLatch done = new CountDownLatch(3); final Runnable runnable = new Runnable() { @Override public void run() { //do nothing } }; private long test() throws InterruptedException { for (int i = 0;i < 3; i++) { executor.execute(new Runnable() { @Override public void run() { ready.countDown(); try { start.await(); runnable.run(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { done.countDown(); } } }); } ready.await(); long startNanos = System.nanoTime(); start.countDown(); done.await(); return System.nanoTime() - startNanos; } }
调用wait方法,应当用循环之内调用 , 永远不要在循环外调用
优先使用notifyAll , 当只有一个线程被唤醒才使用notify
延迟初始化
lazy initializition holder class 模式 : 常见用于单例模式private static class FieldHolder { static final FieldType field = computeFieldValue(); } static FieldType getFieldType() { return FieldHolder.field; }
避免使用线程组
ThreadGroup 已经为过时的API, 没必要继续使用相关文章推荐
- effect java 学习摘要(9) - 序列化
- Java高并发程序设计——学习摘要-第一章
- effect java 学习摘要(5) - 枚举和注解
- Java高并发程序设计——学习摘要-第二章
- effect java 学习摘要(2) - object通用的方法
- effect java 学习摘要(4) - 泛型
- effect java 学习摘要(1) - 创建和销毁对象
- effect java 学习摘要(3) - 类和接口
- effect java 学习摘要(7) - 通用程序设计 和 异常
- effect java 学习摘要(6) - 方法
- Java5 并发学习
- Java 并发 学习 (一)
- 张孝祥java.concurrent线程并发学习笔记 - 传统线程回顾
- JAVA多线程与并发学习总结
- JAVA并发编程学习笔记之synchronized
- JAVA多线程与并发学习总结
- java学习笔记之线程并发库
- Java多线程编程--(9)学习Java5.0 并发编程包--线程工具类
- Java分布式应用学习笔记04JDK的并发包的集合总结
- Java多线程编程--(8)学习Java5.0 并发编程包--线程池、Callable & Future 简介