java 并发编程
基础参考资料 : http://www.mamicode.com/info-detail-517008.html
两个Thread类和Runnable接口
但是在在处理共享数据的场景Thread类不如Runnable实现贡献资源容易
总结:
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
为什么说Runnable能共享资源
原因: 实现Runable类里面的变量能被启动他的 显示贡献使用
例如:
public static void main(String[] args) { |
线程的几个几个常用方法
Wait(); sleep(),join() ,notify方法
其中wait, notify,notifyAll 都是Object对象方法。
Wait,join是线程方法。而且wiat()必须放在synchronized block中,否则会在program runtime时扔出”java.lang.IllegalMonitorStateException“异常
线程数据传递(并发线程类)
构造方法,但是构造方法过于简单并且传递参数有限。‘
通常采用类方法或者类变量进行线程的参数传递。
不管是构造方法还是类方法,类变量都是通过main方法主动推送的,并不是线程自己主动获取数据。
例如: 其实这也是类方法和类变量形式。
jdk 1.5中引入: Callable,Fucture,FuctureTask
Functure就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
Future类位于java.util.concurrent包下,它是一个接口:
1
2
3
4
5
6
7
8
|
public
interface
Future<V> {
boolean
cancel(
boolean
mayInterruptIfRunning);
boolean
isCancelled();
boolean
isDone();
V get()
throws
InterruptedException, ExecutionException;
V get(
long
timeout, TimeUnit unit)
throws
InterruptedException, ExecutionException, TimeoutException;
}
|
在Future接口中声明了5个方法,下面依次解释每个方法的作用:
- cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
- isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
- isDone方法表示任务是否已经完成,若任务完成,则返回true;
- get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
- get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
也就是说Future提供了三种功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。
三.FutureTask
我们先来看一下FutureTask的实现:
1
|
public
class
FutureTask<V>
implements
RunnableFuture<V>
|
FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:
1
2
3
|
public
interface
RunnableFuture<V>
extends
Runnable, Future<V> {
void
run();
}
|
可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
FutureTask提供了2个构造器:
1
2
3
4
|
public
FutureTask(Callable<V> callable) {
}
public
FutureTask(Runnable runnable, V result) {
}
|
事实上,FutureTask是Future接口的一个唯一实现类。
以上是在网络上搜集的资料。以下是读Jave并发实战 --作者: Brian Goetz; Tim Peierls ; Joshua Bloch; Joseph Bowbeer ; David Holmes; Boug Lea; 翻译: 童云兰
书共计:291页
因为书太多讲的是理论,所以我就选读了几章感兴趣或者觉得能用得着的。从第1到第7章再第13章到末尾。这是我选读的章数
关于并发,java工具类来自:java.until.concurrent 类库。
首先我把我看到的关于并发的几个名词先提出来: 内置锁,显示锁,时间锁,条件锁,“原子”性,
常用的线程安全集合或者说同步容器类: Vector,HashTable, currutHashMap,
常用的synchronized,Lock,final,
线程中一般操作的元素: 共享变量,可变变量,volatile变量(稍弱的同步机制)。
类:ThreadLocal类 :get,set方法总能获取当前线程最新值。
ThreadLocal对象通常用于防止对可变的单实例或全局变量进行共享。这个例子可以看JDBC的java连接数据库代码。里面有用到ThreadLocal。
ThreadLocal 使用的对象可以看成是全局变量。在java 5.0之后 话说是有更先进的东西在代替。
内置锁:常见的以synchronized为代表。 同步方法,同步块。同时锁本身也是一种互斥体的一种体现所以我觉得可以叫互斥锁。
Vector: getLast,deleteLast 都有" 先检查再运行 "操作。
ConcurrentHashMap: Java 6 引入ConcurrentSkipListMap,ConcurrentSkipListSet 分别为同步的SortedMap,SortedSet并发的替代品。
BlockingQueue: LinkedBlockingQueue(无界限),ArrayBlockingQueue(有界限)是FIFO队列。
BlockingQueue:维护的是一组线程队列。
Semaphore:同步器,信号类
FutureTask在Executor框架中表示异步任务。它的计算时通过Callable来完成。
Semaohore中管理着一组虚拟的许可。
Executor和ExeutorService
ExeutorService: 生命周期3中状态。运行,关闭,已终止。
注意:数组的数据快速复制,使用Arrays.copyOf(......)。
Future实例:
import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; /** * Created by gan on 2017/3/13. */ public class CallableFuctureTest { public static void main(String[] args) { //new个缓存线程池 ExecutorService ExecutorService = Executors.newCachedThreadPool(); Task task = new Task(); // FutureTask<Integer> futureTask = new FutureTask<Integer>(task); Future<Integer> futureTask = ExecutorService.submit(task); // ExecutorService.submit(futureTask); ExecutorService.shutdown(); try { Boolean b = futureTask.isCancelled(); System.out.println("是否取消: "+b); Integer Integer = futureTask.get(); System.out.println("返回来的结果是: "+Integer); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } class Task implements Callable<Integer>{ private TestCallAble testCallAbl = new TestCallAble("A"); @Override public Integer call() throws Exception { List Arrays = new ArrayList(); for (int i = 0 ;i<10;i++){ Arrays.add(i); } return testCallAbl.getNum(Arrays); } } class TestCallAble{ private String name; private int num; public TestCallAble() { super(); } public TestCallAble(String name) { this.name = name; } public int getNum(List<Integer> listInt){ for (int n: listInt){ this.num +=n; } return num; } }
生产者-消费者-共享变量之间的数据传递实例: http://www.cnblogs.com/linjiqin/p/3217050.html
收集资料: http://blog.csdn.net/xiaozhaorui/article/details/51945589
http://dev.yesky.com/javagaoji/xiancheng/
http://www.cnblogs.com/wq3435/p/6037069.html
http://blog.csdn.net/shenjianox/article/details/9369497
http://www.cnblogs.com/gaotianle/archive/2013/09/07/3306971.html