5 原子变量
java.util.concurrent.atomic包中添加原子变量类。所有原子变量都公开"比较并设置"原语,这些原语都是使用平台上可用的最快本机结构来实现的。原子变量类可以认为是volatile变量的泛化,它扩展了volatile变量的概念,来支持原子条件的比较并设置更新。读取和写入原子变量与读取和写入对volatile变量的访问具有相同的存取语义。concurrent.atomic包中原子变量类共12个,分成4组:计量器,域更新器,数组以及符合变量。最常用的原子变量是计量器:AtomicInteger,AtomicLong,AtomicBoolean以及AtomicReference。这四个class都提供两个constructor, 默认无参和指定参数。默认的constructor的值为零,false或null,依据数据类型初始化对象。他们的set与get方法以atomic的设定与取得值。getAndSet方法能够在返回初始值的时候atomic化的设定变量成新的值。addAndGet与getAndAdd方法提供“前置”与“后”的运算符给指定值的加法运算,这两个method让程序能够对变量增或减一个指定值,包括负值。incrementAndGet,decrementAndGet,getAndIncrement,getAndDecrement方法,提供了前置递增,前置递减,后递增,后递减的功能。compareAndSet和weakCompareAndSet方法,提供了有条件修改程序的方法。这两个method有两个参数,在method启动时预期数据所具有的值,以及要把数据所设定成的值。method只会在变量具有预期值的时候才会将它设置成新值。如果当前值不等于预期值,该变量不会被重新赋值,其method返回false。如果当前值等于预期值会返回true,并且此时值会被设定成新值。这个method的week形式基本也是一样的,区别在于,week形式少了一项保证:如果method放回的是false,该变量不会被变动,但是这并不代表现有值不是预期值。这个method不管初始值是否为预期值都可能会无法更新该值。此外,AtomicInteger和AtomicLong还支持从Integer到int,float,double的转化输出。
以下是使用的一个小例子:
public class ActomicIntegerDemo {
//
private final AtomicInteger counter = new AtomicInteger();
public int getCounter(){
return counter.get();
}
public int increment(){
return counter.incrementAndGet();
}
public int decrement(){
return counter.decrementAndGet();
}
public static void main(String[] args) throws Exception {
final ActomicIntegerDemo atd = new ActomicIntegerDemo();
new Thread(){
public void run(){
for(int i = 0; i < 100; i ++){
atd.increment();
}
}
}.start();
new Thread(){
public void run(){
for(int i = 0; i < 100; i ++){
atd.decrement();
}
}
}.start();
Thread.sleep(2 * 1000);
System.out.println("result = " + atd.getCounter());
}
}
5.1 线程池
Executor为所有线程池的父接口。
ExecutorService接口继承自Executor接口,增加了一些池的管理功能,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。其实现类为AbstractExecutorService,其实现了submit和doInvokeAny重载版本的方法,AbstractExecutorService为一个抽象类,而我们经常用到的ThreadPoolExecutor就是继承自AbstractExecutorService,ThreadPoolExecutor实现了其他所有AbstractExecutorService未实现的方法。
ScheduledExecutorService接口继承自ExecutorService,增加了一些可安排在给定的延迟后运行或定期执行命令的方法。其实现类为ScheduledThreadPoolExecutor,ScheduledThreadPoolExecutor继承自ThreadPoolExecutor并实现了ScheduledExecutorService,它可另行安排在给定的延迟后运行命令,或者定期执行命令,ScheduledThreadPoolExecutor中含有了所有的方法。
Executors为一个工厂类,提供了很多的方法,包括创建ExecutorService,ScheduledExecutorService,ThreadFactory,Callable。
Callable接口类似与Runnable接口,有相同的功能,只不过Callable提供的call方法有返回值,而Runnable的run方法无返回值。
5.2 ThreadLocal变量
ThreadLocal是Thread的局部变量,其为每个使用该变量的线程提供独立的变量副本。所以每一个线程都可以独立的改变自己的副本,而不会影响其他线程所对应的副本。从线程的角度看,目标变量就是线程的本地变量,这也是类名中"Local"所要表达的意思。
ThreadLocal被定义为:
public class ThreadLocal<T>{}
T为线程局部变量的类型。该类定义了4个方法:
protected T initialValue():返回此线程局部变量的当前线程的“初始值”。线程第一次使用get()方法访问变量时将调用次方法,但如果线程之前调用了set方法,则不会对该线程在调用initialValue方法。通常,此方法对每个线程最多调用一次,但如果在调用get后又调用了remove方法,则可能再次调用此方法。该方法返回null,需要我们覆写这个方法。一般使用匿名内部类完成此操作。
public T get():返回此线程局部变量的当前线程副本中的值。如果变量没有用于当前线程的值,则先将其初始化为调用initialValue方法返回的值。
public void set(T value):将此线程局部变量的当前线程副本中的值设置为制定值。
public void remove():移除此线程局部变量当前线程的值。如果此线程局部变量随后被当前线程读取,且这期间当前线程没有设置其值,则将调用其initialValue方法重新初始化其值。
以下是一个小例子,每个线程都产生了独立的顺序号,互补干扰:
public class SequenceNum {
private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>(){
public Integer initialValue(){
return 0;
}
};
public int nextNum(){
seqNum.set(seqNum.get() + 1);
return seqNum.get();
}
private static class Task implements Runnable{
//
private final SequenceNum seq;
public Task(SequenceNum seq ){
this.seq = seq;
}
public void run(){
try {
for(int i = 0; i < 3; i ++){
System.out.println("current thread " + Thread.currentThread().getId() + " , seq num = " + seq.nextNum());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
final SequenceNum seq = new SequenceNum();
new Thread(new Task(seq)).start();
new Thread(new Task(seq)).start();
new Thread(new Task(seq)).start();
}
}
分享到:
相关推荐
为了简化多线程编程,Java提供了一系列工具和API,如`java.util.Timer`和`java.util.concurrent`包,这些工具可以帮助开发者更高效地管理线程间的同步问题。 ##### 1.2 synchronized关键字 `synchronized`关键字是...
concurrent programming in java design principles and patterns .chm
3. **高级并发工具**:随着Java 5的发布,`java.util.concurrent`包引入了许多高级并发工具,如`ExecutorService`、`Future`、`Semaphore`、`CyclicBarrier`和`CountDownLatch`等。这些工具简化了并发代码的编写,...
Java 1.5引入了`java.util.concurrent`包,包含了一系列的并发工具类,如线程池、阻塞队列、并发集合等。这些工具旨在提高并发性能并简化编程模型。例如,`ExecutorService`和`ThreadPoolExecutor`提供了线程池管理...
《Doug Lea, Concurrent Programming in Java Design Principles and Patterns》是一本深入探讨Java并发编程的经典著作,由Doug Lea撰写。这本书对于理解Java平台上的多线程编程和并发设计模式至关重要,是许多Java...
Java平台提供了丰富的API支持并发编程,如`java.util.concurrent`包下的各种类和接口,这些工具可以帮助开发者更高效地管理多线程环境下的任务调度和数据共享问题。 ### Java并发编程基础 #### 1. 多线程基础 - **...
《Java并发编程》一书是由著名并发编程专家Doug Lea所著,他同时也是Java并发包(JUC)的作者,这本书详细介绍了Java多线程编程的基础概念和高级技术。 首先,书中提到了并发编程的基本概念,包括并发模型、设计力...
5. **锁工具的使用**:探索Java中提供的各种锁工具类,如`java.util.concurrent.locks`包下的类。 #### 六、状态依赖性 这部分内容可能进一步探讨了如何根据对象的状态来控制并发行为,以及如何处理状态变化引起的...
Concurrent Programming on Windows 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系...
Concurrent Programming in Java™: Design Principles and Patterns, Second Edition. 介绍并发编程的好的著作,著名的并发大师 Doug Lea的杰作。
Title: Learning Concurrent Programming in Scala, 2nd Edition Author: Aleksandar Prokopec Length: 382 pages Edition: 2nd Revised edition Language: English Publisher: Packt Publishing - ebooks Account ...
《Java并发编程实践》第二版是一本专注于Java编程语言中并发程序设计的著作,由Doug Lea撰写,Addison Wesley出版社于1999年10月出版。这本书旨在为那些熟悉面向对象编程但对并发编程了解不多的开发者提供指导,同时...
例如,使用无锁数据结构或原子操作(`java.util.concurrent.atomic`包)。 3. **避免死锁、活锁和饥饿**:理解并预防这些并发问题至关重要。死锁发生在两个或多个线程相互等待对方释放资源导致僵局;活锁是线程不断...
Concurrent Programming in Java Design Principles and Pattern英文版 2.48M Java并发编程设计原则与模式_第二版(原书中文版) 19.4M Concurrent_Programming_in_Java_Design_Principles_Lecture DougLea
- **标准库**:Java并发工具包(java.util.concurrent)提供了丰富的并发工具类。 - **第三方库**:例如Apache Commons Concurrency等。 ##### 2. 构建库 - **自定义并发组件**:根据项目需求开发特定的并发工具。 ...
《Concepts and Notations for Concurrent Programming》这篇论文由Gregory R. Andrews和Fred B. Schneider撰写,深入探讨了并行编程的核心概念和技术。尽管这是一篇较为古老的文章,但其内容仍然具有很高的参考价值...
资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 封底 Java多线程无处不在,...