参考文章1:https://blog.youkuaiyun.com/androidsj/article/details/80167501
参考文章2: https://blog.youkuaiyun.com/sinat_33087001/article/details/77653741
并发编程juc包学习1-原子类
一.JUC开发包简介
➣ 传统线程编程模型之中为防止死锁等现象的出现(wait()、notify()、
synchronized)时往往会考虑性能、公平性、资源管理等问题,这样加重了程序开发人员的负担;
➣ Java5.0添加了一个新的java.util.concurrent开发包(简称JUC)。
利用此包进行的多线程编程将有效的减少竞争条件(race conditions)和死锁线程。
二.java.util.concurrent核心类
1)Executor:具有Runnable任务的执行者。
2)ExecutorService:一个线程池管理者,其实现类有多种,我会介绍一部分,我们能把Runnable,Callable提交到池中让其调度。
3)Semaphore:一个计数信号量。
4)ReentrantLock:一个可重入的互斥锁定Lock,功能类似synchronized,但要强大的多。
5)Future:是与Runnable,Callable进行交互的接口,比如一个线程执行结束后取返回的结果等,还提供了cancel终止线程。
6)BlockingQueue:阻塞队列。
7)CompletionService:ExecutorService的扩展,可以获得线程执行结果的。
8)CountDownLatch:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
9)CyclicBarrier:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点。
10)Future:表示异步计算的结果。
11)ScheduldExecutorService:一个ExecutorService,可安排在给定的延迟后运行或定期执行的命令。
TimeUnit工具类
TimeUnit是一个时间单元类,该类是一个枚举类型。 这个类之中支持有:日、时、分、秒、毫秒、微妙、纳秒,这些是更加精准的控制单位。
/**
* 测试TimeUnit
*/
public class TestTimeUnit {
public static void main(String[] args) throws InterruptedException {
//休眠一秒
/*TimeUnit.SECONDS.sleep(1);*/
//单位转换
/*long convert = TimeUnit.SECONDS.convert(1, TimeUnit.HOURS);
System.out.println("将一小时转换为秒"+convert);*/
//求3天后的日期
/*long convert = TimeUnit.MILLISECONDS.convert(3, TimeUnit.DAYS);
Date followThreeDays = new Date(System.currentTimeMillis() + convert);
String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(followThreeDays);
System.out.println(format);*/
}
}
原子类
原子操作,是指操作过程不会被中断,保证数据操作是以原子方式进行的;根据修改的数据类型,可以将JUC包中的原子操作类可以分为4类。
1.基本类型: AtomicInteger, AtomicLong, AtomicBoolean ;
2.数组类型: AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray ;
3.引用类型: AtomicReference, AtomicStampedRerence, AtomicMarkableReference ;
4.对象的属性修改类型: AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater 。
AtomicLong的使用
基本类型中的用法都相似,以AtomicLong为例.操作long型的数值.
// 构造函数
AtomicLong()
// 创建值为initialValue的AtomicLong对象
AtomicLong(long initialValue)
// 以原子方式设置当前值为newValue。
final void set(long newValue)
// 获取当前值
final long get()
// 以原子方式将当前值减 1,并返回减1后的值。等价于“--num”
final long decrementAndGet()
// 以原子方式将当前值减 1,并返回减1前的值。等价于“num--”
final long getAndDecrement()
// 以原子方式将当前值加 1,并返回加1后的值。等价于“++num”
final long incrementAndGet()
// 以原子方式将当前值加 1,并返回加1前的值。等价于“num++”
final long getAndIncrement()
// 以原子方式将delta与当前值相加,并返回相加后的值。
final long addAndGet(long delta)
// 以原子方式将delta添加到当前值,并返回相加前的值。
final long getAndAdd(long delta)
// 如果当前值 == expect,则以原子方式将该值设置为update。成功返回true,否则返回false,并且不修改原值。
final boolean compareAndSet(long expect, long update)
// 以原子方式设置当前值为newValue,并返回旧值。
final long getAndSet(long newValue)
// 返回当前值对应的int值
int intValue()
// 获取当前值对应的long值
long longValue()
// 以 float 形式返回当前值
float floatValue()
// 以 double 形式返回当前值
double doubleValue()
// 最后设置为给定值。延时设置变量值,这个等价于set()方法,这里就**类似**于启动一个后台线程如执行修改新值的任务,原线程就不等待修改结果立即返回
final void lazySet(long newValue)
// 如果当前值 == 预期值,则以原子方式将该设置为给定的更新值。
final boolean weakCompareAndSet(long expect, long update)
AtomicLongArray使用
数组类型使用用法相同,AtomicLongArray用于long[]数组的操作
// 创建给定长度的新 AtomicLongArray。
AtomicLongArray(int length)
// 创建与给定数组具有相同长度的新 AtomicLongArray,并从给定数组复制其所有元素。
AtomicLongArray(long[] array)
// 获取位置 i 的当前值。
long get(int i)
// 将位置 i 的元素设置为给定值。
void set(int i, long newValue)
// 以原子方式将给定值添加到索引 i 的元素。
long addAndGet(int i, long delta)
// 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
boolean compareAndSet(int i, long expect, long update)
// 以原子方式将索引 i 的元素减1。
long decrementAndGet(int i)
// 以原子方式将给定值与索引 i 的元素相加。
long getAndAdd(int i, long delta)
// 以原子方式将索引 i 的元素减 1。
long getAndDecrement(int i)
// 以原子方式将索引 i 的元素加 1。
long getAndIncrement(int i)
// 以原子方式将索引 i 的元素加1。
long incrementAndGet(int i)
// 以原子方式将位置 i 的元素设置为给定值,并返回旧值。
long getAndSet(int i, long newValue)
// 最终将位置 i 的元素设置为给定值。
void lazySet(int i, long newValue)
// 返回该数组的长度。
int length()
// 返回数组当前值的字符串表示形式。
String toString()
// 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
boolean weakCompareAndSet(int i, long expect, long update)
使用实例
@Test
public void test01() {
long[] arr = new long[]{12,23,34,53,64,75,86};
AtomicLongArray atomicLongArray = new AtomicLongArray(arr);
atomicLongArray.set(0,99999);
boolean b = atomicLongArray.compareAndSet(0, 999, 10000000001l);
for (int i = 0; i < atomicLongArray.length(); i++) {
long l = atomicLongArray.get(i);
System.out.println(l);
}
System.out.println(b);
}
AtomicReference使用
引用类型(对象)使用该类来进行原子操作
// 使用 null 初始值创建新的 AtomicReference。
AtomicReference()
// 使用给定的初始值创建新的 AtomicReference。
AtomicReference(V initialValue)
// 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
boolean compareAndSet(V expect, V update)
// 获取当前值。
V get()
// 以原子方式设置为给定值,并返回旧值。
V getAndSet(V newValue)
// 最终设置为给定值。
void lazySet(V newValue)
// 设置为给定值。
void set(V newValue)
// 返回当前值的字符串表示形式。
String toString()
// 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
boolean weakCompareAndSet(V expect, V update)
使用实例
@Test
public void test02() {
AtomicReference<User> userAtomic = new AtomicReference<>();
User user1 = new User(100);
User user2 = new User(110);
userAtomic.set(user1);
boolean b = userAtomic.compareAndSet(user1, user2);
User user3 = userAtomic.get();
System.out.println(user3);
System.out.println(user3.equals(user2));
System.out.println(user3.equals(user1));
}
AtomicLongFieldUpdate使用
用于引用类型的对象的字段的更新
// 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。
long addAndGet(T obj, long delta)
// 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。
abstract boolean compareAndSet(T obj, long expect, long update)
// 以原子方式将此更新器管理的给定对象字段当前值减 1。
long decrementAndGet(T obj)
// 获取此更新器管理的在给定对象的字段中保持的当前值。
abstract long get(T obj)
// 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。
long getAndAdd(T obj, long delta)
// 以原子方式将此更新器管理的给定对象字段当前值减 1。
long getAndDecrement(T obj)
// 以原子方式将此更新器管理的给定对象字段的当前值加 1。
long getAndIncrement(T obj)
// 将此更新器管理的给定对象的字段以原子方式设置为给定值,并返回旧值。
long getAndSet(T obj, long newValue)
// 以原子方式将此更新器管理的给定对象字段当前值加 1。
long incrementAndGet(T obj)
// 最后将此更新器管理的给定对象的字段设置为给定更新值。
abstract void lazySet(T obj, long newValue)
// 为对象创建并返回一个具有给定字段的更新器。
static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName)
// 将此更新器管理的给定对象的字段设置为给定更新值。
abstract void set(T obj, long newValue)
// 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。
abstract boolean weakCompareAndSet(T obj, long expect, long update)
使用实例
@Test
public void test03() {
//字段要使用 public volatile int id;
AtomicIntegerFieldUpdater<User> updater = AtomicIntegerFieldUpdater.newUpdater(User.class, "id");
User user1 = new User(1000);
//将user1的id字段的值加2000并且返回新值
int i = updater.addAndGet(user1, 2000);
System.out.println(i);
System.out.println(user1);
}
Java并发编程之JUC包详解
本文深入探讨Java并发编程中的JUC包,涵盖核心类如ExecutorService、Semaphore及ReentrantLock的功能与使用,同时解析原子类如AtomicInteger、AtomicLong及AtomicReference的原理与实践案例。
1310

被折叠的 条评论
为什么被折叠?



