Java并发编程
文章平均质量分 71
总结JAVA并发编程中的常见问题、方法和技术。
坐飞机的狗
熟悉java技术,熟悉java常用设计模式,熟悉java高并发程序设计,了解jvm调优;熟悉基于spring boot+Mybatis的网站后端开发;了解go web开发,熟悉基于RPC + go 微服务开发;熟悉python常用的数据分析库(pandas\sklearn\tensorflow等)、爬虫框架(scrapy)、django后端开发;熟悉mysql的使用;了解前端HTML+CSS+Javascript;了解常用的机器学习算法;熟悉git常用操作。
展开
-
AQS
AQS简介抽象:抽象类,只实现主要逻辑,具体方法由子类实现【模板方法】 队列:使用FIFO队列存储数据 同步:实现了同步的功能使用AQS可以简单的构造出ReetrantLock、Semaphore、ReentrantReadWriteLock、SynchronousQueue、FutureTask等。AQS方法介绍 Protected final int getState(); 返回当前同步状态的值 ...原创 2021-03-19 16:58:41 · 67 阅读 · 0 评论 -
Executor概述
在Java类库中,任务执行的主要抽象不是Thread,而是Executor。public interface Executor { void execute(Runnable command);}它为灵活且强大的异步任务执行框架提供了基础,该框架能支持多种不同类型的任务执行策略。它提供了...原创 2021-03-12 16:50:48 · 683 阅读 · 0 评论 -
CAS
基本概念悲观锁:它总是认为每次访问共享资源时会发生冲突,所以必须对每次数据操作加上锁,以保证临界区的程序同一时间只能有一个线程在执行。乐观锁:乐观锁总是假设对共享资源的访问没有冲突,线程可以不停地执行,无需加锁也无需等待。而一旦多个线程发生冲突,乐观锁通常是使用一种称为CAS的技术来保证线程执行的安全性。由于无锁操作中没有锁的存在,因此不可能出现死锁的情,也就是说乐观锁天生免疫死锁。乐观锁多用于“读多写少”的环境,避免频繁加锁影响性能;而悲观锁多用于“写多读少”的环境,避免频繁失败和重试影原创 2021-01-28 21:18:02 · 285 阅读 · 0 评论 -
Java线程间的通信
当需要多个线程之间相互协作的时候,就需要用到Java线程的通信方法。Java中,锁的概念都是基于对象的,所以又称为对象锁。1. 锁与同步package chapter7;public class ObjectLock { // 类属性只有一个[不管创建多少个实例],保证同一个锁 private static Object lock = new Object(); // 可尝试去掉static怎么保证线程安全 static class ThreadA im原创 2021-01-24 17:48:43 · 121 阅读 · 0 评论 -
线程组的常用方法及数据结构
线程组的常用方法1. 获取当前的线程组的名字// 或者当前运行线程所属的线程组Thread.currentThread().getThreadGroup().getName();2. 复制线程组// 复制一个线程数组到一个线程组Thread[] threads = new Thread[2]; ThreadGroup threadGroup = new ThreadGroup("copyGroup");threadGroup.enumerate(threads);3. 线程原创 2021-01-23 16:50:53 · 192 阅读 · 0 评论 -
Java并发编程实战笔记(第七章--取消与关闭)
要使任务和线程能安全地停下来,并不是一件容易的事。如果某个任务、线程、服务立即停止,会使共享的数据结构处于不一致的状态。当需要停止时,它们首先会清除当前正在执行的工作,然后结束。1. 任务取消如果外部代码能在某个操作正常完成之前将其置入"完成"状态,那么这个操作就称为可以取消的。取消某个操作的原因:用户请求取消 有时间限制的操作:计时器超时 应用程序事件 错误:运行期错误 关闭:当程序或者服务关闭时设置某个“已请求取消”标志,而任务定期查看这个标志,如果取消,那么任务将提前结束。.原创 2021-01-22 12:58:00 · 201 阅读 · 0 评论 -
Java并发编程实战笔记(第六章--3)
public class FutureRenderer{ private final ExecutorService executor = ...; void renderPage(CharSequence source) { final List<ImageInfo> imageInfos = sanForImageInfo(source); callable<List<ImageData> task = new .原创 2021-01-19 21:25:30 · 164 阅读 · 0 评论 -
实现/创建线程的四种方式
方式1:通过Thread方式2:实现Runnable接口方式3:实现Callable接口import java.util.ArrayList;import java.util.List;import java.util.concurrent.*;class MyThread implements Callable<String>{ private String s; public MyThread(String s) { ...原创 2021-01-19 13:08:58 · 167 阅读 · 1 评论 -
Java中的锁
synchronized的不足之处:保证即使在只读操作下,同一时间也只能有一个线程执行。 无法知道线程是否成功获取到锁。 一个阻塞,所有线程等待。由于synchronized的不足,引入了Locks中的其它锁。public class Counter{ private int count = 0; // synchronized实现的版本 public int inc(){ synchronized(this){ // 锁为当前类的实例原创 2021-01-16 22:14:03 · 106 阅读 · 0 评论 -
常见的阻塞队列
线程池的实现原理是基于生产者-消费者模式,最重要的是对资源的管理。需要让多个线程操作资源,很容易造成线程安全问题,造成重复消费和死锁。JDK为了避免这样的问题,为我们提供了阻塞队列(BlockingQueue),我们只需要往队列中存、取,而不需要去关注资源(任务)的安全问题。...原创 2021-01-11 21:06:34 · 332 阅读 · 0 评论 -
四种常见的线程池
1. newCachedThreadPoolpublic static ExecutorService newCachedThreadPool(){ return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());}运行流程如下:提交任务到线程池。原创 2021-01-06 21:27:04 · 204 阅读 · 0 评论 -
线程池主要的任务处理流程
线程池处理任务的核心方法是execute,来看看JDK1.8源码中的ThreadPoolExecutor处理线程任务的方法:// JDK1.8public void execute(Runnable command){ // 线程池的执行单元是Runnable if (commmand == null){ throw new NullPointerException(); int c = ctl.get(); // ctl记录任务数 // 1. 当前线原创 2021-01-02 22:01:50 · 775 阅读 · 0 评论 -
Java并发编程实战笔记 (第六章--1)
第六章 任务执行6.1 在线程中执行任务围绕**“任务执行”来设计应用程序结构时,第一步就是找出清晰的任务边界**。各个任务之间是相互独立的;任务并不依赖于其它任务的状态,结果或者边界效应。独立性有助于实现并发,因为如果存在足够多的处理资源,那么这些独立的任务都可以并行执行。大多数服务器应用程序都提供了一种自然的任务边界选择方式:以独立的客服请求为边界。/** 串行的Web服务器**/class SingleThreadWebServer{ public static void main(S原创 2020-12-29 22:32:38 · 111 阅读 · 0 评论 -
Java并发编程实战笔记 (第五章--2)
5.5.2 FutureTaskFutureTask也可以用作闭锁。(FutureTask实现了Future语义,表示一种抽象的可生成结果的计算)。FutureTask表示的计算是通过Callable来实现的,相当于一种可生成结果的Runnable,有三种状态:执行完成【正常结束、取消、异常】。Future.get的行为取决于任务的状态。如果任务已经完成,那么get会立即返回结果,否则get将阻塞直到任务进入完成状态,然后返回结果或者抛出异常。// 支持泛型@FunctionInterfacepu原创 2020-12-22 20:58:56 · 94 阅读 · 0 评论 -
Java并发编程实战笔记 (第五章--1)
5.1.1 同步容器类的问题同步容器类(Vector、Hashtable)都是线程安全的,但在某些情况下可能需要额外的客服端加锁来保护复合操作。复合操作:1)迭代(反复访问元素,直到遍历完容器中所有元素);2)跳转(根据指定顺序找到当前元素的下一个元素)以及条件运算。在同步容器中,这些复合操作在没有客服端加锁的情况下任然是线程安全的,但但其他线程并发地修改容器时,它们可能会表现出意料之外的行为。package chapter5;import java.util.Vector;/** *原创 2020-12-06 13:04:18 · 147 阅读 · 1 评论 -
Java并发编程实战笔记(第四章--2)
4.4 在现有的线程安全类中添加功能由于Java类库中包含许多有用的“基础模块”类,应该优先选择重用这些现有的类而不是创建新的类:重用能降低开发工作量、开发风险(因为现有的类都已经通过测试)以及维护成本。eg:现需要一个线程安全的链表,它需要一个原子的“若没有则添加”的操作。这个操作包括两个步骤:1)检查该元素是否已经存在,2)如果存在就不再添加。因此这个必须是线程安全的,那么这个操作“若没有则添加”必须是原子操作。...原创 2020-11-14 20:54:18 · 72 阅读 · 0 评论 -
Java并发编程实战笔记(第四章--1)
第四章–对象的组合4.1 设计线程安全的类在设计线程安全类的过程中,需要包含以下三个基本要素:找出构成对象的所有变量–域;【对于含有n个基本类型域的对象,其状态及时这些构成的n元组】找出约束状态变量的不可变性条件。建立对象状态的并发访问管理策略。public final class Counter{ private long value = 0; public synchronized long getValue(){ return value ; } public synch原创 2020-11-11 21:54:11 · 108 阅读 · 0 评论 -
JAVA并发编程实战笔记(第三章)
3.1 可见性在没有同步的情况下,编译器、处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整,在缺乏足够同步的多线程程序中,要想对内存操作的执行顺序的操作顺序进行判断,几乎无法得出正确的结论。package chapter3;/** * 在代码中没有使用足够的同步机制,因此无法保证主线程写入的ready值和number值对于线程来时是可见的。 */public class NoVisibility { private static boolean ready ; p原创 2020-11-08 20:21:30 · 141 阅读 · 2 评论 -
java并发编程实战笔记(第二章)
2.1 什么是线程安全性1)在方法计算过程中的临时状态仅存在于线程栈上的局部变量中,并且只能由正在执行的线程访问。由于线程访问无状态对象的行为并不会影响其他线程中操作的正确性,因此无状态对象时线程安全的。无状态对象一定是线程安全的。2.2 原子性@NotThreadSafepublic class UnsafeCountingFactorizer implemnets Servlet{ private long count = 0; public long getCount(){ retur原创 2020-10-30 20:09:44 · 1095 阅读 · 1 评论 -
java并发中的三个问题
在java并发编程中,会遇到三个问题:原子性可见性有序性1)原子性原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。对于操作:i++s三、参考作者:Matrix海子 出处:http://www.cnblogs.com/dolphin0520/...原创 2019-11-04 15:06:19 · 111 阅读 · 0 评论