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();
}
}
分享到:
相关推荐
Concurrent Programming in Java Design Principles and Pattern英文版 2.48M Java并发编程设计原则与模式_第二版(原书中文版) 19.4M Concurrent_Programming_in_Java_Design_Principles_Lecture DougLea
详细的java 多线程相关知识 并附有相关练习题
Concurrent Programming in Java - Design Principles and Patterns
java concurrent 多线程 PPT
concurrent programming in java design principles and patterns .chm
Doug Lea, Concurrent Programming in Java Design Principles and Patterns
详细介绍java多线程编程的各个基础概念。JUC作者doug lea著
在并发或多线程应用程序中使用Java编程语言的简介。
word版本的资料,网上...Concurrent Programming in Java™: Design Principles and Patterns, Second Edition Doug Lea Publisher: Addison Wesley Second Edition October 01, 1999 ISBN: 0-201-31009-0, 432 pages
Doug Lea Java Concurrent Programming
This book shows readers how to use the Java platform's threading model more precisely by helping them to understand the patterns and tradeoffs associated with concurrent programming
Concurrent - Programming in Java.pdf,ppt,Doug Lea
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并发编程-设计原则与模式(Concurrent.Programming.in.Java-Design.Principles.and.Patterns(Second.Edition))(中英版)
Concurrent Programming in Java Thread 看看吧
资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 封底 Java多线程无处不在,...