![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
Java并发编程(多线程)
Java并发编程相关知识
奔跑的废柴
卧久者行必远,伏久者飞必高
展开
-
多线程LeetCode 1226. 哲学家进餐 Java代码
题目https://leetcode-cn.com/problems/the-dining-philosophers/限制4人同时用餐并且先拿左手边的筷子class DiningPhilosophers { Semaphore s1=new Semaphore(4); Semaphore[] c=new Semaphore[5]; public DiningPhilosophers() { for(int i=0;i<5;i++){原创 2021-01-20 15:57:32 · 256 阅读 · 2 评论 -
多线程LeetCode 1195. 交替打印字符串 Java代码
题目https://leetcode-cn.com/problems/fizz-buzz-multithreaded/CyclicBarrier我用信号量写了半天都没写对,不活了class FizzBuzz { private int n; private static CyclicBarrier barrier = new CyclicBarrier(4); public FizzBuzz(int n) { this.n = n; }原创 2021-01-20 14:55:54 · 125 阅读 · 0 评论 -
多线程LeetCode 1117. H2O 生成 Java代码
题目https://leetcode-cn.com/problems/building-h2o/Semaphoreclass H2O { //需要两次H 一次O public H2O() { } Semaphore s1=new Semaphore(2); Semaphore s2=new Semaphore(0); public void hydrogen(Runnable releaseHydrogen) throws Inte原创 2021-01-20 14:01:59 · 198 阅读 · 0 评论 -
多线程LeetCode 1116. 打印零与奇偶数 Java代码
题目https://leetcode-cn.com/problems/print-zero-even-odd/Semaphore超时class ZeroEvenOdd { private int n; //打印 零 奇数 零 偶数 零 奇数 零 偶数 Semaphore s1=new Semaphore(1); Semaphore s2=new Semaphore(0); Semaphore s3=new Semaphore(0); public原创 2021-01-20 11:58:27 · 279 阅读 · 0 评论 -
多线程LeetCode 1115. 交替打印FooBar Java代码
题目https://leetcode-cn.com/problems/print-foobar-alternately/Semaphoreclass FooBar { private int n; Semaphore s1=new Semaphore(0); Semaphore s2=new Semaphore(1); public FooBar(int n) { this.n = n; } public void foo(Runna原创 2021-01-20 11:26:17 · 145 阅读 · 2 评论 -
多线程LeetCode 1114. 按序打印 Java代码
题目https://leetcode-cn.com/problems/print-in-order/synchronized只打印三次,所以是这样的代码。class Foo { public final Object obj=new Object(); public volatile int k=1; public Foo() { } public void first(Runnable printFirst) throws Interr原创 2021-01-20 10:41:04 · 180 阅读 · 0 评论 -
Java创建线程的方式
1.继承Thread类创建线程继承Thread类,重写run方法,调用start方法启动。public class MyThread extends Thread{//继承Thread类 public void run(){ //重写run方法 }}public class Main { public static void main(String[] args){ new MyThread().start();//创建并启动线程 }}2.实现Runnable接口创原创 2020-11-21 10:43:04 · 673 阅读 · 0 评论 -
【Java多线程】Java中的原子操作类:原子整数&原子引用&原子数组&原子更新字段类&Unsafe对象
1.原子整数J.U.C并发包提供了AtomicBoolean,AtomicInteger,AtomicLong。1.1 AtomicInteger1.1.1api:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html方法都是原子的,利用CAS保证了线程安全。举例:incrementAndGet():自增,相当于++igetAndAdd(int delta):相当于获取这原创 2020-11-10 12:10:17 · 467 阅读 · 0 评论 -
多线程面试题1
看到不会的就查一查,然后放这问题:Java中线程与操作系统的线程关系答案:由上面源码可以看到:Java的多线程是直接调用linux的多线程函数实现的每个继承java.lang.Thread的类,调用start方法之后,都调用start0()的native方法;start0()的native方法在openjdk里调用的是JVM_StartThread;JVM_StartThread最终调用的是操作系统的pthread_create()函数,有四个参数,我们写的run方法就是该函数的第三.原创 2020-11-08 20:19:28 · 1360 阅读 · 1 评论 -
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask
1.介绍1.1 Executor框架的两级调度模型应用程序通过Executor框架控制上层的调度;而下层的调度由操作系统内核控制,下层的调度不受应用程序的控制。1.2 Executor框架的结构与成员Executor框架主要由以下3大部分组成:1.任务。包括被执行任务需要实现的接口:Runnable接口或Callable接口。2.任务的执行。包括任务执行机制的核心接口Executor,以及继承自Executor的ExecutorService接口。Executor框架有两个关键类实现了Exec原创 2020-10-22 19:18:25 · 575 阅读 · 0 评论 -
【Java并发编程的艺术】Java中的并发工具类:CountDownLatch&CyclicBarrier&Semaphore&Exchanger
1.CountDownLatchCountDownLatch允许一个或多个线程等待其他线程完成操作。CountDownLatch的构造函数接受一个int类型的参数作为计数器,如果你想等待N个点完成,这里就传入N。这里说的N个点,可以是N个线程,也可以是1个线程里的N个执行步骤。调用countDown方法时,N就会减1,CountDownLatch的await方法会阻塞当前线程,直到N变成0。CountDownLatch不可能重新初始化或修改CountDownLatch对象的内部计数器的值。2.Cy原创 2020-10-21 16:37:03 · 187 阅读 · 0 评论 -
【Java并发编程的艺术】Java并发容器和框架:Fork/Join框架
什么是Fork/join框架原创 2020-10-20 15:43:42 · 135 阅读 · 0 评论 -
【Java并发编程的艺术】Java并发容器和框架:Java中的阻塞队列
1.什么是阻塞队列阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加元素的线程,消费者是 从队列里取元素的线程。阻塞队列就是生产者用来存放元素、消费者用来获取元素的容器。阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。1)支持阻塞的插入方法:意思是当队列满时,队列会阻塞插入元素的线程,直到队列不 满。2)支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空。在阻塞队列不可用时,这两个附加操作提供了4种处理方式原创 2020-10-20 15:17:11 · 231 阅读 · 1 评论 -
【Java并发编程的艺术】Java并发容器和框架:ConcurrentLinkedQueue
如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法。使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现。非阻塞的实现方式则可以使用CAS循环的方式来实现。ConcurrentLinkedQueue就是非阻塞的。ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序。它采用了“wait-free”算法(即CAS算法)来实现。1.结构ConcurrentLinkedQ原创 2020-10-20 14:31:00 · 115 阅读 · 0 评论 -
【Java并发编程的艺术】Java并发容器和框架:ConcurrentHashMap
1.为什么要用ConcurrentHashMap1.1 HashMap应该开一篇讲HashMap,先占坑1.2 HashTable1.3 ConcurrentHashMap2.结构3.初始化4.操作4.1 get4.2 put4.3 size原创 2020-10-20 10:06:05 · 139 阅读 · 0 评论 -
【Java多线程】interrupt中断
1.理解中断中断可以理解为线程的一个标志位属性,它表示一个运行中的线程是否被其他线程进行了中断操作。线程通过检查自身被中断来进行响应。这句话的意思是,中断并不能打断影响线程的运行,只是一个标记属性,被中断的线程自身可以根据标记属性决定接下来做什么操作。//举例线程通过isInterrupted()来进行判断是否被中断。也可以调用静态方法Thread.interrupted()方法判断,它会对当前线程的中断标识位进行复位。如果该线程已处于终结状态,即使该线程被中断过,再调用该线程对象的isInte原创 2020-10-18 16:41:47 · 362 阅读 · 2 评论 -
【Java多线程】Condition接口
拉拉原创 2020-10-18 13:58:50 · 154 阅读 · 0 评论 -
【Java多线程】读写锁ReentrantReadWriteLock
1.读写锁介绍锁(如Mutex和ReentrantLock)基本都是排他锁,在同一时刻只能同一个线程访问。而读写锁在同时可以允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。2.ReentrantReadWriteLock 特性3.ReentrantReadWriteLock APIReadWriteLock接口仅定义了获取读锁和写锁的两个方法,即readLock()方法和writeLock()方法。而其实现——ReentrantReadWriteLock,除了接口方法之原创 2020-10-18 13:12:00 · 276 阅读 · 0 评论 -
【Java多线程】可重入锁ReentrantLock
可重入锁ReentrantLock,就是支持可重入的锁,它表示该锁能够支持一个线程对资源的重复加锁。此外,ReentrantLock还支持获取锁时的公平和非公平性选择。1.公平性锁和非公平性锁的区别公平性锁:锁的获取顺序符合请求的绝对时间顺序(FIFO)。公平性锁每次都是从同步队列中的第一个节点获取到锁。在tryAcquire方法中,需要判断同步队列中当前节点是否有前驱节点,如果有,表示有线程比当前线程更早地请求获取锁,因此需要等待前驱线程获取并释放锁之后才能继续获取锁。非公平性锁:Reentra原创 2020-10-18 09:51:07 · 203 阅读 · 2 评论 -
【Java并发编程的艺术】Java中的锁:Lock&AQS&LockSupport工具
1.Lock接口锁是用来控制多个线程访问共享资源的方式。在Java SE5 Lock接口出现之前,通过synchronized实现锁功能。1.1 Lock接口提供的synchronized关键字不具备的主要特性特性描述尝试非阻塞的获取锁当前线程尝试获取锁,如果这一时刻没有被其他线程获取到,则成功获取并持有锁能被中断的获取锁与synchronized不同,获取到锁的线程能够响应中断,当获取到锁的线程被中断时,中断异常将会被抛出,同时锁会被释放超时获取锁在指定的截止时原创 2020-10-16 19:51:27 · 222 阅读 · 0 评论 -
【Java多线程】volatile原理&happens-before规则
1.Java 内存模型中的可见性、原子性和有序性1.1 可见性可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。1.2 原子性原子是世界上的最小单位,具有不可分割性。1.3 有序性Java 语言提供了 volatile 和 synchronized 两个关键字来保证线程之间操作的有序性,volatile 是因为其本身包含“禁止指令重排序”的语义,synchronized 是由“一个变量在同一个时刻只允许一条线程对其进行 lock 操作”这条规则获得的,此规则决定了持有同一个对原创 2020-10-15 18:17:08 · 307 阅读 · 1 评论 -
【Java多线程】synchronized关键字使用&原理&优化(偏向锁、轻量级锁、重量级锁的介绍)
1.synchronized使用1.1 修饰一个类 synchronized(ClassName.class)锁定这个类的所有对象1.2 加在静态方法上锁定这个类的所有对象1.3 加在实例对象上 synchronized(this)锁住的是实例对象1.4 加在代码块上或普通方法上修饰代码块是大括号括起来的范围2.synchronized原理2.1 Monitor2.1.1 对象头biased_lock代表是不是偏向锁,后面两位(01)代表加锁状态。2.1.2 Monitor(锁原创 2020-10-15 09:31:29 · 179 阅读 · 0 评论 -
【Java并发编程的艺术】线程池
1.合理使用线程池的好处1.降低资源消耗2.提高响应速度3.提高线程的可管理性2.线程池的使用2.1 线程池的创建new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,milliseconds,runnableTaskQueue,handler)1.corePoolSize(线程池的基本大小):提交一个任务后,线程池就创建一个新线程来执行任务。即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数原创 2020-10-14 14:37:15 · 157 阅读 · 0 评论 -
【Java多线程】线程简介-线程的几种状态及其转换
线程的状态状态名称说明NEW初始状态,线程被构建,但还没有调用start()方法RUNNABLE运行状态,Java线程将操作系统中的就绪和运行状态笼统称作“运行中”BLOCKED阻塞状态,表示线程阻塞于锁WAITING等待状态,表示线程进入等待状态。进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断)TIME_WAITING超时等待状态,该状态不同于WAITING,它是可以在指定的时间自行返回的TERMINATED终止状态,表示原创 2020-10-14 13:40:05 · 116 阅读 · 0 评论 -
【Java并发编程的艺术】第2章 原子操作的实现原理
1.Java如何实现原子操作1.1 使用循环CASCAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。1.1.1 CAS实现原子操作的三大问题1.1.1.1 ABA问题CAS需要在操作值的时候检查有没有变化,如果没有变化则更新。但当值A->B->A时,中间变化过,但CAS检查不到变化。解决ABA问题的方法是加上版本号,如1A->2B->3A。从Java1.5开始,JDK的Atomic包里提原创 2020-09-25 14:58:17 · 126 阅读 · 0 评论