线程
文章平均质量分 69
xiaozhu0301
这个作者很懒,什么都没留下…
展开
-
什么是IO多路复用
先百度或者知乎,找到这篇文章 [1]IO 多路复用是什么意思?文中提到: 第一种好理解,就是来一个请求,fork一个进程,第二种提到I/O多路复用使用单个线程实现的,作者肯定没有写错,因为后面的文章也都是写的线程,我的问题是为什么不是进程来管理?参考文章[2] 里面的code 给出的是通过一个进程来服务多个client 连接请求. 我理解这是通过单进程的里面的一个线程来处理的,所以这里进程线程就不作区分.还有,下面引文中一个问题问的很好“Q:那这样子,在读取...转载 2021-01-06 17:21:31 · 428 阅读 · 0 评论 -
java线程池
接口类Executor 线程的定义和线程的执行分开 execute 马上执行ExecutorService接口类 extends Executor submit 异步执行 get 方法是阻塞的 直到submit的结果返回才会取到Callable 这个就是为了线程池而设计的 得到线程执行的返回值 类似于runnable 但是有返回值Future 存储将来返回的执行结果FutureTask Future + RunnableCompletableFuture 管理一堆任务完成...原创 2021-01-05 15:58:36 · 79 阅读 · 0 评论 -
Queue 系列
copyOnWriteArrayList 写时复制 插入数据的时候 先把原来的数据copy一份,在将元素插入进去,然后将引用指向新的值,这样写的时候加锁,读的时候不加锁为什么还需要复制 因为Array的长度是一定的之前的ArrayList 在读的时候 需要将写的进程停掉,才可以进行读Queue 是线程安全的offer 放数据成功返回true 失败返回falseadd 放数据失败,返回false,并抛出异常peek 读数据pool 取出数据(读并且删除掉)-----------..原创 2020-12-31 14:55:49 · 75 阅读 · 0 评论 -
java中强引用 弱引用 软引用 虚引用 总结
ThreadLocal 一个线程一个map(ThreadLocalMap) map的key 为当前对象ThreadLocal value为对应泛型的值ThreadLocal 的原理强引用: 平时定义变量 如 Student s = new Student(); s即强引用软引用 SoftReference<Student> s = new SoftReference<>(new Student()) 定义的变量为软引用 主要用于缓存,需要新的空间的时候,可以...原创 2020-12-30 20:57:05 · 179 阅读 · 0 评论 -
java 中的强引用 软引用 弱引用 虚引用
主要是为了更好的进行内存管理而设置的一套机制,粗俗的说就是不同的引用垃圾回收的力度不同。强引用:只要引用存在,垃圾回收器永远不会回收Object obj = new Object();obj.equels(new Object());//可直接通过obj取得对应的对象而这样 obj对象对后面new Object的一个强引用,只有当obj这个引用被释放之后,对象才会被释放掉,这也是我们经常所用到的编码形式。软引用:非必须引用,内存溢出之前进行回收,可以通过以下代码实现.转载 2020-12-30 20:03:45 · 107 阅读 · 0 评论 -
Semaphore 限流
Semaphore,是用于控制一组线程访问资源。举个例子,老师上课,同学需要上厕所,老师准备了3个令牌,拿到令牌的同学就可以去上厕所,上完厕所的同学需要归还令牌。这样就最多同时只有3名同学上厕所。这就是Semaphore的应用场景。 Semaphore的构造函数可初始化令牌数量、是否公平锁。如果是公平锁,先申请令牌的可以先获取。 acquire() 和release()分别是获取和释放令牌,acquire(int) 和release(int) 分别是获取和释放多个令牌。Semaphore...转载 2020-12-25 12:11:40 · 145 阅读 · 0 评论 -
LockSupport
LockSupport是一个线程工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞,也可以在任意位置唤醒。它的内部其实两类主要的方法:park(停车阻塞线程)和unpark(启动唤醒线程)。 如果线程先被unpark,再进行park,则直接放行import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.LockSupport;public class LockSupportTest { publ原创 2020-12-25 13:14:10 · 144 阅读 · 0 评论 -
ReentrantReadWriteLock
读写锁 可以生成两把锁 一个读锁(读锁共享锁),一个写锁(互斥锁)import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockTest { static ReadWriteLock readWriteL.原创 2020-12-25 11:27:09 · 71 阅读 · 0 评论 -
Phaser的使用
分阶段进行,按照一定的流程执行,比如举行婚礼1、新郎新娘入场2、其它宾客入场3、所有人开始吃饭4、所有人离场5 新郎新娘洞房import java.util.concurrent.Phaser;import java.util.concurrent.TimeUnit;public class PhaserTest { static MarriagePhaser phaser = new MarriagePhaser(); static void milliSleep原创 2020-12-25 11:08:18 · 98 阅读 · 0 评论 -
CountDownLatch和CyclicBarrier
CyclicBarrier在用法上其实跟CountDownLatch十分相似,但是前者功能更加强大。CountDownLatch举例:CountDownLatch countDownLatch=new CountDownLatch(n); 当程序多次执行countDownLatch.countDown();导致计数器n=0时,阻塞的线程都将同时被唤醒。但是此时的n已经是等于0了,也就是说这个计数器就是一次性的。CyclicBarrier举例:CyclicBarrier cycl.转载 2020-12-25 10:46:23 · 107 阅读 · 0 评论 -
CountDownLatch 的用法
1.背景:countDownLatch是在java1.5被引入,跟它一起被引入的工具类还有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。 存在于java.util.cucurrent包下。2.概念countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。(等待其它一组线程执行完毕后,该线程再执行,需要依赖其它线程的执行结果) 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器转载 2020-12-25 10:33:32 · 116 阅读 · 0 评论 -
一个线程持有锁后,同步方法可以交互执行吗
一个线程里面的多个同步方法不能同时进行,必须等待一个方法执行完以后,另一个才能执行,代码如下import java.util.concurrent.TimeUnit;public class ThreadSysnTest { int a = 0; synchronized void add(){ for(int i=0;i<10000000;i++){ a++; } } synchronized voi原创 2020-12-25 09:34:14 · 109 阅读 · 0 评论 -
synchronized 和ReentrantLock 的区别
锁类型:synchronized 悲观锁(排它锁、互斥锁)、非公平锁(当其它进程来的时候,如果锁已被占用,就必须wait,开始阻塞,等待锁释放。谁抢到归谁占有,不需要排队)synchronized 有一个锁升级的概念 从偏向锁(开始有资源争抢时)->轻量级锁(自旋锁 自旋=10)->重量级锁ReentrantLock 需要分情况调用lock()方法,获取到的锁就是悲观锁调用tryLock()方法,获取到的锁为CAS的,有一个指定时间的参数,这样无法锁定,或者在指定时间内...原创 2020-12-24 21:04:50 · 220 阅读 · 1 评论 -
悲观锁、乐观锁概念
一、并发控制当程序中可能出现并发的情况时,就需要通过一定的手段来保证在并发情况下数据的准确性,通过这种手段保证了当前用户和其他用户一起操作时,所得到的结果和他单独操作时的结果是一样的。这种手段就叫做并发控制。并发控制的目的是保证一个用户的工作不会对另一个用户的工作产生不合理的影响。没有做好并发控制,就可能导致脏读、幻读和不可重复读等问题。常说的并发控制,一般都和数据库管理系统(DBMS)有关。在 DBMS 中的并发控制的任务,是确保在多个事务同时存取数据库中同一数据时,不破坏事务的隔离.转载 2020-12-24 20:28:59 · 159 阅读 · 1 评论 -
ReentrantLock NonfairSync FairSync
结构首先看看ReentranLock结构,它实现Lock接口,也拥有Sync ,NonfairSync, FairSync三个内部类,( NonfairSync, FairSync )-----继承------->Sync ------继承-------> AbstractQueuedSynchronizerNonfairSync ,FairSync 重写了AQS 的 tryAcquire构造方式:public ReentrantLock() {sync =...转载 2020-12-24 20:19:02 · 140 阅读 · 1 评论 -
如何优化synchronized锁
锁细化 :只对需要争抢的资源加锁,不争抢的不加锁锁粗化: 若争抢资源比较激烈,这样可以把多个细锁,合成一个粗锁加锁的对象是final的 这样可以防止对象的指针移动,如Object o = new Object();synchronized(o){}如果在其他的线程中将o = new Object();即指针改变,则锁的对象就改变了,相当于锁失效...原创 2020-12-23 19:37:45 · 139 阅读 · 0 评论 -
volatile和synchronized对比
volatile并不能保证多个线程共同修改 代码块的代码 时所带来的不一致问题,也就是说volatile不能替代synchronizedvolitile 只能保证可见性不能保证原子性,即替代不了sysnimport java.util.ArrayList;import java.util.List;public class VolatileVsSync { volatile int count = 0; void m() { for (int i = 0; i < 10.原创 2020-12-23 19:30:49 · 420 阅读 · 0 评论 -
为什么Java中synchronized同步的对象不能是Integer、String、Long类型
原因是Java的自动封箱和解箱操作在作怪。这里的i++实际上是i = new Integer(i+1),所以执行完i++后,i已经不是原来的对象了,同步块自然就无效了Long 类型同理,String是因为String定义的变量会放在常量池中,如果多个线程定义的String变量的值相等,则锁无效String的值一致时指向的地址是一致的,其实两个线程锁的是同一个对象。而在实际工作中,String值相同的情况时有发生,而出现问题有不容易发现。...原创 2020-12-23 16:54:25 · 1086 阅读 · 1 评论 -
java中的CAS原理
一、什么是CAS? 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令。 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。 操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成(摘自维基本科) JAVA1.5开始引...转载 2020-12-23 16:44:41 · 101 阅读 · 0 评论 -
锁的几种状态
偏向锁有资源争用的时候升级为自旋锁自旋锁10次后 升级为重量级锁自旋锁 属于用户态的 占用cpu 适用:加锁的代码执行时间比较短,线程数量比较少重量级锁 os 内核态 不占用cpu 在旁边竞争的线程进入等待队列,等待不占用cpu资源,需要等待cpu唤醒 适用于: 执行时间长,线程数量比较多用系统锁锁只能升级不能降级...原创 2020-12-23 14:31:36 · 301 阅读 · 0 评论 -
偏向锁是什么
偏向锁操作流程偏向锁,顾名思义,它会偏向于第一个访问锁的线程,如果在接下来的运行过程中,该锁没有被其他的线程访问,则持有偏向锁的线程将永远不需要触发同步但是从我们跑的代码输出却看不到偏向锁这个东东。为啥对象实例化出来之后,对象头里是不支持偏向的呢?其实是JVM搞的鬼,JVM虽然默认启用偏向锁,但启动后4秒内并不支持。可以通过-XX:BiasedLockingStartupDelay=0参数将JVM启动后支持偏向锁的延迟时间设置为0,这样就可以看到偏向锁的输出了: 代码也改动一...转载 2020-12-23 14:27:22 · 2206 阅读 · 0 评论 -
对象头是什么东西
对象头,顾名思义,就是对象的头。对象是实例化出来的,实例化的前提是必须有类这个模板。举个不大恰当的例子,人类就是个类,你我他就是人类实例化出来的对象。我们的头,自然就是对象头。我们的头有口鼻眼耳,对象头也有一些东西,主要包含两部分:Mark Word(标记字)和Class Pointer(类指针),如果是数组对象还得再加一项Array Length(数组长度)。 对象头为啥要有这些东东?Mark Word用来标记运行时信息(每个对象各不相同),Class Pointer用来指向生成该对象所在的类(认祖转载 2020-12-23 14:12:11 · 2518 阅读 · 0 评论 -
可重入锁synchronized 和 ReentrantLock
JVM的 synchronized 是可重入锁,即可以多次获得相同的锁(就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁)new Thread(new Runnable() { @Override public void run() { synchronized (this) { System.out.println("第1次获取锁,这个锁是:" + this);转载 2020-12-23 13:11:47 · 154 阅读 · 0 评论 -
线程的join方法
join()方法的作用就是让主线程等待子线程执行结束之后再运行主线程。下面示例中t2 为主线程,需要等待子线程t1 执行完成再执行使用场景,线程2依赖于线程1执行的返回结果在线程2 中调用线程1的join方法,即把cpu资源让给线程1 public static void main(String[] args) throws Exception{ Thread t1 = new Thread(()->{ try { T.原创 2020-12-23 11:22:47 · 14815 阅读 · 0 评论 -
关于线程同步(5种同步方式)
为何要使用同步? java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用, 从而保证了该变量的唯一性和准确性。1.同步方法 即有synchronized关键字修饰的方法。 由于java的每个对...原创 2016-05-20 13:46:30 · 393 阅读 · 0 评论 -
java线程池ThreadPoolExecutor类使用详解
本文转自:https://www.cnblogs.com/dafanjoy/p/9729358.html在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量;另一方面线程的细节管理交给线程池处理,优化了资源的开销。而线程池不允许使用Executors去创建,而要通过ThreadPoolEx...转载 2019-07-23 17:04:42 · 170 阅读 · 0 评论 -
线程池的几种状态
线程池的5种状态:Running、ShutDown、Stop、Tidying、Terminated。1、RUNNING(1) 状态说明:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理。(02) 状态切换:线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0!private fin...转载 2019-07-24 16:11:19 · 538 阅读 · 0 评论 -
ExecutorService线程池的使用
ExecutorService线程池讲解ExecutorService 建立多线程的步骤:1。定义线程类 class Handler implements Runnable{ } 2。建立ExecutorService线程池 ExecutorService executorService = Executors.newCachedThreadPool(); ...转载 2015-10-23 10:53:13 · 300 阅读 · 0 评论 -
什么情况下线程会让出CPU
sleep(),yield(),wait(),await(),线程结束Thread.sleep();sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。在多线程争用的...原创 2019-07-22 18:17:10 · 3693 阅读 · 1 评论 -
线程池
多线程目的:充分利用CPU做事(多做事)线程的本质:将代码送给CPU执行线程池的本质:线程池的工作原理:接收任务,放入仓库(任务队列BlockingQueue) 工作线程从仓库取任务,执行 当没有任务时,线程阻塞,当有任务时,唤醒线程执行BlockingQueue如何定义线程池的个数? 任务分为两种:IO型任务和计算型任务,web项目中大多数任务为I...原创 2019-07-23 12:12:54 · 81 阅读 · 0 评论 -
创建线程池的工厂类Executors
newFixedThreadPool(int nThreads) 创建一个固定大小、任务队列容量无界的线程池。池的核心线程数=最大线程数=nThreads newCachedThreadPool()创建一个大小无界的缓冲线程池。它的任务队列是一个同步队列。任务加入到池中,如果池中有空闲线程,则用空闲线程执行,如无则创建新线程执行。池中的线程空闲超过60秒,将被销毁释放。池中的线程数随任务的多少变...原创 2019-07-23 13:03:46 · 388 阅读 · 0 评论 -
实现线程的两种方式
Java中线程的创建有两种方式: 1. 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中2. 通过实现Runnable接口,实例化Thread类 在实际应用中,我们经常用到多线程,如车站的售票系统,车站的各个售票口相当于各个线程。当我们做这个系统的时候可能会想到两种方式来实现,继承Thread类或实现Runnable接口,现在看一下转载 2016-01-20 11:49:48 · 301 阅读 · 0 评论