在这里,我们将给大家分享关于java.util.concurrent.locks.LockSupport源码的知识,让您更了解java.util.scanner源码的本质,同时也会涉及到如何更有效地A
在这里,我们将给大家分享关于java.util.concurrent.locks.LockSupport 源码的知识,让您更了解java.util.scanner源码的本质,同时也会涉及到如何更有效地AG 百家乐最新官网《 787977.tv 蝙蝠 14735340 》java 并发编程 (2):Java 多线程 - java.util.concurrent 高级工具、Android-Studio-2.3错误:java.util.concurrent.ExecutionException:java.lang.RuntimeException:AAPT进程尚未准备好接收命令、com.intellij.util.ReflectionUtil 对方法 java.util.ResourceBundle.setParent(java.util.ResourceBundle) 的非法反射访问、CompletableFuture 源码详解之 java.util.concurrent.CompletableFuture#supplyAsync (java.util.function.Suppl...的内容。
本文目录一览:- java.util.concurrent.locks.LockSupport 源码(java.util.scanner源码)
- AG 百家乐最新官网《 787977.tv 蝙蝠 14735340 》java 并发编程 (2):Java 多线程 - java.util.concurrent 高级工具
- Android-Studio-2.3错误:java.util.concurrent.ExecutionException:java.lang.RuntimeException:AAPT进程尚未准备好接收命令
- com.intellij.util.ReflectionUtil 对方法 java.util.ResourceBundle.setParent(java.util.ResourceBundle) 的非法反射访问
- CompletableFuture 源码详解之 java.util.concurrent.CompletableFuture#supplyAsync (java.util.function.Suppl...
java.util.concurrent.locks.LockSupport 源码(java.util.scanner源码)
LockSupport 主要利用了 Unsafe 类中提供的 part 和 unpart 两个方法.而 LockSupport 类暴露出来的两个核心接口也是 part 和 unpart 两个.
相关类图:
java.util.concurrent.locks.LockSupport 源码:
package java.util.concurrent.locks;
import sun.misc.Unsafe;
public class LockSupport {
//构造方法私有化
private LockSupport() {}
//把Thread实例t的parkBlocker字段的值设置为arg
private static void setBlocker(Thread t, Object arg) {
UNSAFE.putObject(t, parkBlockerOffset, arg);
}
//获取对象t中parkBlocker字段的值
public static Object getBlocker(Thread t) {
if (t == null)
throw new NullPointerException();
return UNSAFE.getObjectVolatile(t, parkBlockerOffset);
}
//取消阻塞线程,如果线程已经处于非阻塞状态,那么下次调用park时不会阻塞线程
public static void unpark(Thread thread) {
if (thread != null)//判断是否为空,然后调用unsafe的unpark
UNSAFE.unpark(thread);
}
// 使当前调用线程在给定对象上阻塞(不能保证一定阻塞,
// 因为如果之前在非阻塞状态调用了unpark 方法的话,此次调用park方法就不会阻塞线程)
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);在调用park阻塞当前线程之前,先记录当前线程的blocker
UNSAFE.park(false, 0L);//调用park阻塞当前线程
setBlocker(t, null);//当线程可以继续执行下去时,再将parkBlocker设置为null
}
// 使当前线程在blocker对象上阻塞给定的纳秒时间
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(false, nanos);
setBlocker(t, null);
}
}
// 使当前线程在blocker对象上阻塞到给定的时间点
// 这个时间点是从Epoch time(1970-01-01 00:00:00 UTC)开始算起的某个具体的时间点
public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(true, deadline);
setBlocker(t, null);
}
// 阻塞当前线程
public static void park() {
UNSAFE.park(false, 0L);
}
//在指定的时限前阻塞当前线程
public static void parkNanos(long nanos) {
if (nanos > 0)
UNSAFE.park(false, nanos);
}
// 使当前线程在blocker对象上阻塞到给定的时间点
// 这个时间点是从Epoch time(1970-01-01 00:00:00 UTC)开始算起的某个具体的时间点
public static void parkUntil(long deadline) {
UNSAFE.park(true, deadline);
}
//返回伪随机初始化或更新的二级种子
static final int nextSecondarySeed() {
int r;
Thread t = Thread.currentThread();
if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
r ^= r << 13; // xorshift
r ^= r >>> 17;
r ^= r << 5;
}
else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)
r = 1; // avoid zero
UNSAFE.putInt(t, SECONDARY, r);
return r;
}
//引用Unsafe类
private static final sun.misc.Unsafe UNSAFE;
//Thread类中parkBlocker字段的偏移量
private static final long parkBlockerOffset;
//Thread 类中threadLocalRandomSeed字段的偏移量
private static final long SEED;
//Thread 类中threadLocalRandomProbe字段的偏移量
private static final long PROBE;
//Thread 类中threadLocalRandomSecondarySeed字段的偏移量
private static final long SECONDARY;
//初始化上面4个字段的值
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> tk = Thread.class;
parkBlockerOffset = UNSAFE.objectFieldOffset
(tk.getDeclaredField("parkBlocker"));
SEED = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSeed"));
PROBE = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomProbe"));
SECONDARY = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSecondarySeed"));
} catch (Exception ex) { throw new Error(ex); }
}
}
类 LockSupport
java.util.concurrent.locks.LockSupport extends Object
用来创建锁和其他同步类的基本线程阻塞原语。
此类以及每个使用它的线程与一个许可关联(从 Semaphore
类的意义上说)。如果该许可可用,并且可在进程中使用,则调用 park
将立即返回;否则可能 阻塞。如果许可尚不可用,则可以调用 unpark
使其可用。(但与 Semaphore 不同的是,许可不能累积,并且最多只能有一个许可。)
park
和 unpark
方法提供了阻塞和解除阻塞线程的有效方法,并且不会遇到导致过时方法 Thread.suspend
和 Thread.resume
因为以下目的变得不可用的问题:由于许可的存在,调用 park
的线程和另一个试图将其 unpark
的线程之间的竞争将保持活性。此外,如果调用者线程被中断,并且支持超时,则 park
将返回。park
方法还可以在其他任何时间 “毫无理由” 地返回,因此通常必须在重新检查返回条件的循环里调用此方法。从这个意义上说,park
是 “忙碌等待” 的一种优化,它不会浪费这么多的时间进行自旋,但是必须将它与 unpark
配对使用才更高效。
三种形式的 park
还各自支持一个 blocker
对象参数。此对象在线程受阻塞时被记录,以允许监视工具和诊断工具确定线程受阻塞的原因。(这样的工具可以使用方法 getBlocker(java.lang.Thread)
访问 blocker。)建议最好使用这些形式,而不是不带此参数的原始形式。在锁实现中提供的作为 blocker
的普通参数是 this
。
这些方法被设计用来作为创建高级同步实用工具的工具,对于大多数并发控制应用程序而言,它们本身并不是很有用。park
方法仅设计用于以下形式的构造:
while (!canProceed()){
...
LockSupport.park(this);
}
在这里,在调用 park
之前, canProceed
和其他任何动作都不会锁定或阻塞。因为每个线程只与一个许可关联, park
的任何中间使用都可能干扰其预期效果。
示例用法。 以下是一个先进先出 (first-in-first-out) 非重入锁类的框架。
class FIFOMutex {
private final AtomicBoolean locked = new AtomicBoolean(false);
private final Queue<Thread> waiters
= new ConcurrentLinkedQueue<Thread>();
public void lock() {
boolean wasInterrupted = false;
Thread current = Thread.currentThread();
waiters.add(current);
// Block while not first in queue or cannot acquire lock
while (waiters.peek() != current ||
!locked.compareAndSet(false, true)) {
LockSupport.park(this);
if (Thread.interrupted()) // ignore interrupts while waiting
wasInterrupted = true;
}
waiters.remove();
if (wasInterrupted) // reassert interrupt status on exit
current.interrupt();
}
public void unlock() {
locked.set(false);
LockSupport.unpark(waiters.peek());
}
}
先进先出锁就是先申请锁的线程最先获得锁的资源,实现上采用了队列再加上 LockSupport.park。
- 将当前调用 lock 的线程加入队列
- 如果等待队列的队首元素不是当前线程或者 locked 为 true,则说明有线程已经持有了锁,那么调用 park 阻塞其余的线程。
- 如果队首元素是当前线程且 locked 为 false,则说明前面已经没有人持有锁,删除队首元素也就是当前的线程,然后当前线程继续正常执行。
- 执行完后调用 unlock 方法将锁变量修改为 false, 并解除队首线程的阻塞状态。此时的队首元素继续之前的判断。
方法摘要
static Object |
getBlocker(Thread t) 返回提供给最近一次尚未解除阻塞的 park 方法调用的 blocker 对象,如果该调用不受阻塞,则返回 null。 |
static void |
park() 为了线程调度,禁用当前线程,除非许可可用。 |
static void |
park(Object blocker) 为了线程调度,在许可可用之前禁用当前线程。 |
static void |
parkNanos(long nanos) 为了线程调度禁用当前线程,最多等待指定的等待时间,除非许可可用。 |
static void |
parkNanos(Object blocker, long nanos) 为了线程调度,在许可可用前禁用当前线程,并最多等待指定的等待时间。 |
static void |
parkUntil(long deadline) 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。 |
static void |
parkUntil(Object blocker, long deadline) 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。 |
static void |
unpark(Thread thread) 如果给定线程的许可尚不可用,则使其可用。 |
unpark
public static void unpark(Thread thread)
如果给定线程的许可尚不可用,则使其可用。如果线程在 park
上受阻塞,则它将解除其阻塞状态。否则,保证下一次调用 park
不会受阻塞。如果给定线程尚未启动,则无法保证此操作有任何效果。
参数:
thread
- 要执行 unpark 操作的线程;该参数为 null
表示此操作没有任何效果。
park
public static void park(Object blocker)
为了线程调度,在许可可用之前禁用当前线程。
如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下三种情况之一前,使其处于休眠状态:
- 其他某个线程调用将当前线程作为目标调用
unpark
;或者 - 其他某个线程中断当前线程;或者
- 该调用不合逻辑地(即毫无理由地)返回。
此方法不报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定返回时该线程的中断状态。
参数:
blocker
- 导致此线程暂停的同步对象
parkNanos
public static void parkNanos(Object blocker,long nanos)
为了线程调度,在许可可用前禁用当前线程,并最多等待指定的等待时间。
如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下四种情况之一前,使其处于休眠状态:
- 其他某个线程将当前线程作为目标调用
unpark
;或者 - 其他某个线程中断当前线程;或者
- 已超过指定的等待时间;或者
- 该调用不合逻辑地(即毫无理由地)返回。
此方法不报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定返回时该线程的中断状态或已过的时间。
参数:
blocker
- 导致此线程暂停的同步对象
nanos
- 要等待的最大毫秒数
parkUntil
public static void parkUntil(Object blocker, long deadline)
为了线程调度,在指定的时限前禁用当前线程,除非许可可用。
如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下四种情况之一前,使其处于休眠状态:
- 其他某个线程将当前线程作为目标调用
unpark
;或者 - 其他某个线程中断当前线程;或者
- 指定时限已过;或者
- 该调用不合逻辑地(即毫无理由地)返回。
此方法不报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定返回时该线程的中断状态或当前时间。
参数:
blocker
- 导致此线程暂停的同步对象
deadline
- 要等待的绝对时间,用相对于历元 (Epoch) 的毫秒数值表示
getBlocker
public static Object getBlocker(Thread t)
返回提供给最近一次尚未解除阻塞的 park 方法调用的 blocker 对象,如果该调用不受阻塞,则返回 null。返回的值只是一个瞬间快照,即由于未解除阻塞或者在不同的 blocker 对象上受阻而具有的线程。
park
public static void park()
为了线程调度,禁用当前线程,除非许可可用。
如果许可可用,则使用该许可,并且该调用立即返回;调用 park 后有以下三种情况,能使线程继续执行下去,否则就休眠:
- 其他某个线程将当前线程作为目标调用
unpark
;或者 - 其他某个线程中断当前线程;或者
- 该调用不合逻辑地(即毫无理由地)返回。
此方法并不报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定线程返回时的中断状态。
parkNanos
public static void parkNanos(long nanos)
为了线程调度禁用当前线程,最多等待指定的等待时间,除非许可可用。
如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下四种情况之一以前,将其处于休眠状态:
- 其他某个线程将当前线程作为目标调用
unpark
;或者 - 其他某个线程中断当前线程;或者
- 已超过指定的等待时间;或者
- 该调用不合逻辑地(即无缘无故地)返回。
此方法并不报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定线程返回时的中断状态或所用的时间。
参数:
nanos
- 要等待的最大毫秒数
parkUntil
public static void parkUntil(long deadline)
为了线程调度,在指定的时限前禁用当前线程,除非许可可用。
如果许可可用,则使用该许可,并且调用立即返回;否则,为线程调度禁用当前线程,并在发生以下四种情况之一以前,将其处于休眠状态:
- 其他某个线程将当前线程作为目标调用
unpark
;或者 - 其他某个线程中断当前线程;或者
- 指定的最后期限已过;或者
- 该调用不合逻辑地(即毫无理由地)返回。
此方法并不报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定线程返回时的中断状态或当前时间。
参数:
deadline
- 要等待的绝对时间,用相对于历元的毫秒数值表示
AG 百家乐最新官网《 787977.tv 蝙蝠 14735340 》java 并发编程 (2):Java 多线程 - java.util.concurrent 高级工具
高级多线程控制类
Java1.5 提供了一个非常高效实用的多线程包:java.util.concurrent, 提供了大量高级工具,可以帮助开发者编写高效、易维护、结构清晰的 Java 多线程程序。
ThreadLocal 类
ThreadLocal 类 用来保存线程的独立变量。对一个线程类(继承自 Thread)
当使用 ThreadLocal 维护变量时,ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。常用于用户登录控制,如记录 session 信息。
实现:每个 Thread 都持有一个 TreadLocalMap 类型的变量(该类是一个轻量级的 Map,功能与 map 一样,区别是桶里放的是 entry 而不是 entry 的链表。功能还是一个 map。)以本身为 key,以目标为 value。
主要方法是 get () 和 set (T a),set 之后在 map 里维护一个 threadLocal -> a,get 时将 a 返回。ThreadLocal 是一个特殊的容器。
原子类(AtomicInteger、AtomicBoolean……)
如果使用 atomic wrapper class 如 atomicInteger,或者使用自己保证原子的操作,则等同于 synchronized
AtomicInteger.compareAndSet (int expect,int update)// 返回值为 boolean
AtomicReference
对于 AtomicReference 来讲,也许对象会出现,属性丢失的情况,即 oldObject == current,但是 oldObject.getPropertyA != current.getPropertyA。
这时候,AtomicStampedReference 就派上用场了。这也是一个很常用的思路,即加上版本号
Lock 类
lock: 在 java.util.concurrent 包内。共有三个实现:
- ReentrantLock
- ReentrantReadWriteLock.ReadLock
- ReentrantReadWriteLock.WriteLock
主要目的是和 synchronized 一样, 两者都是为了解决同步问题,处理资源争端而产生的技术。功能类似但有一些区别。
区别如下:
- lock 更灵活,可以自由定义多把锁的枷锁解锁顺序(synchronized 要按照先加的后解顺序)
- 提供多种加锁方案,lock 阻塞式,trylock 无阻塞式,lockInterruptily 可打断式, 还有 trylock 的带超时时间版本。
- 本质上和监视器锁(即 synchronized 是一样的)
- 能力越大,责任越大,必须控制好加锁和解锁,否则会导致灾难。
- 和 Condition 类的结合。
- 性能更高,synchronized 和 Lock 性能对比,如下图:

ReentrantLock 的使用
可重入的意义在于持有锁的线程可以继续持有,并且要释放对等的次数后才真正释放该锁。
private java.util.concurrent.locks.Lock lock = new ReentrantLock();
public void method() {
try {
lock.lock(); //获取到锁lock,同步块
} finally {
lock.unlock();//释放锁lock
}
}
复制
- ReentrantLock 比 synchronized 功能更强大,主要体现:
- ReentrantLock 具有公平策略的选择。
- ReentrantLock 可以在获取锁的时候,可有条件性地获取,可以设置等待时间,很有效地避免死锁。
- 如 tryLock () 和 tryLock (long timeout, TimeUnit unit)
- ReentrantLock 可以获取锁的各种信息,用于监控锁的各种状态。
- ReentrantLock 可以灵活实现多路通知,即 Condition 的运用。
公平锁与非公平锁
ReentrantLock 默认是非公平锁,允许线程 “抢占插队” 获取锁。公平锁则是线程依照请求的顺序获取锁,近似 FIFO 的策略方式。
锁的使用
- lock () 阻塞式地获取锁,只有在获取到锁后才处理 interrupt 信息
- lockInterruptibly () 阻塞式地获取锁,立即处理 interrupt 信息,并抛出异常
- tryLock () 尝试获取锁,不管成功失败,都立即返回 true、false,注意的是即使已将此锁设置为使用公平排序策略,tryLock () 仍然可以打开公平性去插队抢占。如果希望遵守此锁的公平设置,则使用 tryLock (0, TimeUnit.SECONDS),它几乎是等效的 (也检测中断)。
- tryLock (long timeout, TimeUnit unit) 在 timeout 时间内阻塞式地获取锁,成功返回 true,超时返回 false,同时立即处理 interrupt 信息,并抛出异常。
如果想使用一个允许闯入公平锁的定时 tryLock,那么可以将定时形式和不定时形式组合在一起:
if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
private java.util.concurrent.locks.ReentrantLock lock = new ReentrantLock();
public void testMethod() {
try {
if (lock.tryLock(1, TimeUnit.SECONDS)) {
//获取到锁lock,同步块
} else {
//没有获取到锁lock
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread())
//如果当前线程持有锁lock,则释放锁lock
lock.unlock();
}
}
复制
条件 Condition 的使用
条件 Condition 可以由锁 lock 来创建,实现多路通知的机制。
具有 await、signal、signalAll 的方法,与 wait/notify 类似,需要在获取锁后方能调用。
private final java.util.concurrent.locks.Lock lock = new ReentrantLock();
private final java.util.concurrent.locks.Condition condition = lock.newCondition();
public void await() {
try {
lock.lock(); //获取到锁lock
condition.await();//等待condition通信信号,释放condition锁
//接到condition通信
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();//释放对象锁lock
}
}
复制
ReentrantReadWriteLock 的使用
ReentrantReadWriteLock 是对 ReentrantLock 更进一步的扩展,实现了读锁 readLock ()(共享锁) 和写锁 writeLock ()(独占锁),实现读写分离。读和读之间不会互斥,读和写、写和读、写和写之间才会互斥,提升了读写的性能。
读锁示例:
private final java.util.concurrent.locks.ReadWriteLock lock = new ReentrantReadWriteLock();
public void method() {
try {
lock.readLock().lock();//获取到读锁readLock,同步块
} finally {
lock.readLock().unlock();//释放读锁readLock
}
}
复制
写锁示例:
private final java.util.concurrent.locks.ReadWriteLock lock = new ReentrantReadWriteLock();
public void method() {
try {
lock.writeLock().lock(); //获取到写锁writeLock,同步块
} finally {
lock.writeLock().unlock(); //释放写锁writeLock
}
}
复制
容器类
同步容器与异步容器概览
同步容器
包括两部分:
- 一个是早期 JDK 的 Vector、Hashtable;
- 一个是它们的同系容器,JDK1.2 加入的同步包装类,使用 Collections.synchronizedXxx 工厂方法创建。
Map<String, Integer> hashmapSync = Collections.synchronizedMap(new HashMap<>());
同步容器都是线程安全的,一次只有一个线程访问容器的状态。
但在某些场景下可能需要加锁来保护复合操作。
复合类操作如:新增、删除、迭代、跳转以及条件运算。
这些复合操作在多线程并发的修改容器时,可能会表现出意外的行为,
最经典的便是 ConcurrentModificationException,
原因是当容器迭代的过程中,被并发的修改了内容,这是由于早期迭代器设计的时候并没有考虑并发修改的问题。
其底层的机制无非就是用传统的 synchronized 关键字对每个公用的方法都进行同步,使得每次只能有一个线程访问容器的状态。这很明显不满足我们今天互联网时代高并发的需求,在保证线程安全的同时,也必须有足够好的性能。
并发容器
与 Collections.synchronizedXxx () 同步容器等相比,util.concurrent 中引入的并发容器主要解决了两个问题:
- 根据具体场景进行设计,尽量避免 synchronized,提供并发性。
- 定义了一些并发安全的复合操作,并且保证并发环境下的迭代操作不会出错。
util.concurrent 中容器在迭代时,可以不封装在 synchronized 中,可以保证不抛异常,但是未必每次看到的都是 "最新的、当前的" 数据。
Map<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();
ConcurrentHashMap 替代同步的 Map 即 (Collections.synchronized (new HashMap ()))。
众所周知,HashMap 是根据散列值分段存储的,同步 Map 在同步的时候会锁住整个 Map,而 ConcurrentHashMap 在设计存储的时候引入了段落 Segment 定义,同步的时候只需要锁住根据散列值锁住了散列值所在的段落即可,大幅度提升了性能。ConcurrentHashMap 也增加了对常用复合操作的支持,比如 "若没有则添加":putIfAbsent (),替换:replace ()。这 2 个操作都是原子操作。注意的是 ConcurrentHashMap 弱化了 size () 和 isEmpty () 方法,并发情况尽量少用,避免导致可能的加锁 (当然也可能不加锁获得值,如果 map 数量没有变化的话)。 CopyOnWriteArrayList 和 CopyOnWriteArraySet 分别代替 List 和 Set,主要是在遍历操作为主的情况下来代替同步的 List 和同步的 Set,这也就是上面所述的思路:迭代过程要保证不出错,除了加锁,另外一种方法就是 "克隆" 容器对象。--- 缺点也明显,占有内存,且数据最终一致,但数据实时不一定一致,一般用于读多写少的并发场景。
- ConcurrentSkipListMap 可以在高效并发中替代 SoredMap (例如用 Collections.synchronzedMap 包装的 TreeMap)。
- ConcurrentSkipListSet 可以在高效并发中替代 SoredSet (例如用 Collections.synchronzedSet 包装的 TreeMap)。
- ConcurrentLinkedQuerue 是一个先进先出的队列。它是非阻塞队列。注意尽量用 isEmpty,而不是 size ();
CountDownLatch 闭锁的使用
管理类
管理类的概念比较泛,用于管理线程,本身不是多线程的,但提供了一些机制来利用上述的工具做一些封装。
了解到的值得一提的管理类:ThreadPoolExecutor 和 JMX 框架下的系统级管理类 ThreadMXBean
ThreadPoolExecutor
如果不了解这个类,应该了解前面提到的 ExecutorService,开一个自己的线程池非常方便:
ExecutorService e = Executors.newCachedThreadPool();
ExecutorService e = Executors.newSingleThreadExecutor();
ExecutorService e = Executors.newFixedThreadPool(3);
// 第一种是可变大小线程池,按照任务数来分配线程,
// 第二种是单线程池,相当于FixedThreadPool(1)
// 第三种是固定大小线程池。
// 然后运行
e.execute(new MyRunnableImpl());
复制
该类内部是通过 ThreadPoolExecutor 实现的,掌握该类有助于理解线程池的管理,本质上,他们都是 ThreadPoolExecutor 类的各种实现版本。
参考文章:
Java 多线程并发编程一览笔录 https://www.cnblogs.com/yw0219/p/10597041.html
Java 中的多线程你只要看这一篇就够了 https://juejin.im/entry/57339fe82e958a0066bf284f
Android-Studio-2.3错误:java.util.concurrent.ExecutionException:java.lang.RuntimeException:AAPT进程尚未准备好接收命令
我弹出这些错误消息:
错误:java.util.concurrent.ExecutionException:java.lang.RuntimeException:AAPT进程尚未准备好接收命令
错误:任务’:app:mergeDebugResources’的执行失败.
Error: java.util.concurrent.ExecutionException: java.lang.RuntimeException: AAPT process not ready to receive commands
我去过很多网站,但我找不到解决这个问题的办法
顺便说一句,我已经尝试将我的gradle降级到23.0.0或23.0.1,但它仍然无效. Android-Studio要求我下载25.0.0版本但是当我这样做时,上面的错误消息仍然出现!
有没有人有解决方案,我会非常感激:)
解决方法
我假设你试图在Ubuntu上安装android studio?如果我是对的,你可以查看你有哪个操作系统.如果它是64位操作系统,您可以尝试使用以下内容:
sudo apt-get install lib32stdc++6 sudo apt-get install lib32z1
也许有帮助.
com.intellij.util.ReflectionUtil 对方法 java.util.ResourceBundle.setParent(java.util.ResourceBundle) 的非法反射访问
如何解决com.intellij.util.ReflectionUtil 对方法 java.util.ResourceBundle.setParent(java.util.ResourceBundle) 的非法反射访问
我在 VSCode 中编写了一些 kotlin 代码
其中之一是:
public void readCSV(String fileName) {
fileLocation = fileName;
File csvFile = new File(fileName);
Scanner sfile;
// noOfColumns = 0;
// noOfRows = 0;
data = new ArrayList<ArrayList>();
int colCounter = 0;
int rowCounter = 0;
try {
sfile = new Scanner(csvFile);
while (sfile.hasNextLine()) {
String aLine = sfile.nextLine();
Scanner sline = new Scanner(aLine);
sline.useDelimiter(",");
colCounter = 0;
while (sline.hasNext()) {
if (rowCounter == 0)
data.add(new ArrayList<String>());
data.get(colCounter).add(sline.next());
colCounter++;
}
rowCounter++;
sline.close();
}
// noOfColumns = colCounter;
// noOfRows = rowCounter;
sfile.close();
} catch (FileNotFoundException e) {
System.out.println("File to read " + csvFile + " not found!");
}
}
当我运行它时,我得到:
fun main() {
println("Hello world")
}
它有效,但我无法隐藏或修复警告,我使用 JDK 15
我在 IntelliJ 上没有收到这些警告
CompletableFuture 源码详解之 java.util.concurrent.CompletableFuture#supplyAsync (java.util.function.Suppl...
/**
* Returns a new CompletableFuture that is asynchronously completed
* by a task running in the {@link ForkJoinPool#commonPool()} with
* the value obtained by calling the given Supplier.
*
* @param supplier a function returning the value to be used
* to complete the returned CompletableFuture
* @param <U> the function''s return type
* @return the new CompletableFuture
*/
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
CompletableFuture 下的 supplyAsync 方法是一个执行异步任务且有返回结果的任务,使用例子如下:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
/**
* 测试类
* @author yangchangkui
*/
public class TestMy {
public static void main(String[] args) throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "hello";
});
//判断是否已经完成
System.out.println("耗时:"+(System.currentTimeMillis()-start)+",isDone:"+completableFuture.isDone());
//阻塞获取结果
String result = completableFuture.get();
System.out.println("耗时:"+(System.currentTimeMillis()-start)+",result:"+result);
//判断是否已经完成
System.out.println("耗时:"+(System.currentTimeMillis()-start)+",isDone:"+completableFuture.isDone());
}
}
执行结果如下,显然,达到了异步执行的效果,比如在一些调用很多外部接口的聚合接口,只要接口不作为入参,那就可以进行异步执行,最后阻塞拿结果,提高接口的 QPS,提高系统性能。
关于java.util.concurrent.locks.LockSupport 源码和java.util.scanner源码的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于AG 百家乐最新官网《 787977.tv 蝙蝠 14735340 》java 并发编程 (2):Java 多线程 - java.util.concurrent 高级工具、Android-Studio-2.3错误:java.util.concurrent.ExecutionException:java.lang.RuntimeException:AAPT进程尚未准备好接收命令、com.intellij.util.ReflectionUtil 对方法 java.util.ResourceBundle.setParent(java.util.ResourceBundle) 的非法反射访问、CompletableFuture 源码详解之 java.util.concurrent.CompletableFuture#supplyAsync (java.util.function.Suppl...的相关知识,请在本站寻找。
本文标签: