Java并发学习(一)
来源:互联网 发布:日本社交软件 编辑:程序博客网 时间:2024/05/22 11:40
1.要响应线程中断
线程接受到中断信号后要及时的对中断进行响应。响应方式:
1.捕捉InterruptException
for(;;){try {doXXX();} catch (InterruptedException e) {System.out.println(getName() +" is interrupt");break;}catch (Exception e) {e.printStackTrace();}}
2.判断当前线程状态
for(;;){doXXX();//判断是否被中断if(Thread.interrupted()){System.out.println(getName() +" is interrupt");break;}}
接收到中断信号后,需要结束当前线程,可行的方式有return,break等,比较优雅的方式是抛出InterruptedException异常。代码如下:
public void foo() throws InterruptedException { if (Thread.interrupted()) { throw new InterruptedException(); }}
2.使用ThreadLocal
顾名思义它是local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。
- 不使用ThreadLocal的测试结果
private int sum2 = 0;public int getSum(){sum2++;return sum2;}public static void main(String[] args){new CurrentTest().threadLocal();}public void threadLocal(){TestThreadLocal t1 = new TestThreadLocal(this);TestThreadLocal t2 = new TestThreadLocal(this);TestThreadLocal t3 = new TestThreadLocal(this);t1.setName("t1");t2.setName("t2");t3.setName("t3");t1.start();t2.start();t3.start();}class TestThreadLocal extends Thread{CurrentTest c;public TestThreadLocal(CurrentTest c) {this.c = c;}@Overridepublic void run() {int sum = this.c.getSum();while(sum<10){System.out.println(getName()+" sum is "+sum);sum = this.c.getSum();}}}输出结果:出现并发问题
- 使用ThreadLocal的测试结果
private ThreadLocal<Integer> sum = new ThreadLocal<Integer>(){protected Integer initialValue() {return 0;};};public int getSum(){sum.set(sum.get() + 1);return sum.get();}public static void main(String[] args){new CurrentTest().threadLocal();}public void threadLocal(){TestThreadLocal t1 = new TestThreadLocal(this);TestThreadLocal t2 = new TestThreadLocal(this);TestThreadLocal t3 = new TestThreadLocal(this);t1.setName("t1");t2.setName("t2");t3.setName("t3");t1.start();t2.start();t3.start();}class TestThreadLocal extends Thread{CurrentTest c;public TestThreadLocal(CurrentTest c) {this.c = c;}@Overridepublic void run() {int sum = this.c.getSum();while(sum<10){System.out.println(getName()+" sum is "+sum);sum = this.c.getSum();}}}输出结果:每个线程都从1一直计数到9,线程间没有出现并发问题
事实上ThreadLocal是牺牲空间来减少高并发所消耗的时间,其原理是每个Thread维护一个Map集合,集合的Key是ThreadLocal对象,value是共享变量的副本,这样每次Thread修改变量时就会直接修改本地保存的变量副本。具体ThreadLocal源代码如下:
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }注意:使用ThreadLocal,一般都是声明在静态变量中,如果不断的创建ThreadLocal而且没有调用其remove方法,将会导致内存泄露。
3.任务的提交者和执行者
为了方便并发执行任务,出现了一种专门用来执行任务的实现,也就是Executor。由此,任务提交者不需要再创建管理线程,使用更方便,也减少了开销。java.util.concurrent.Executors是Executor的工厂类,通过Executors可以创建你所需要的Executor。
常用的子类如下图:(转自:http://blog.csdn.net/qq_29882587/article/details/78658675)
更广泛的使用是ExecutorSevice接口,主要API如下:
其中submit方法可以接收两类参数,Runable和Callable,Callable是需要有返回值的。submit方法返回Feture对象。Feture对象用于线程间的通信,Future通常包括get(阻塞至任务完成), cancel,get(timeout)(等待一段时间)等等。Future也用于异步变同步的场景。
阅读全文
0 0
- Java 并发 学习 (一)
- Java并发学习(一)
- java 并发学习(一)
- java 并发机制学习(一)
- Java并发编程学习笔记(一)
- Java并发编程学习(一)
- java并发编程学习笔记(一)
- 学习java并发编程实战(一)
- JAVA高并发学习(一)
- 【JAVA并发学习一】并发和多线程
- java 并发深入学习一
- Java并发学习笔记一
- Java并发学习(一)-Executor
- 学习笔记-Java并发(一)
- Java并发(一)
- Java并发(一)
- 学习java并发编程实战的一些心得体会(一)
- 关于Java多线程和并发运行的学习(一)
- C++ 内存数据结构与二进制文件之间的序列化和反序列化
- Android memory corruption debugger
- 数组名=&数组名
- 由主页界面引出的几个知识点(五)
- 大数据
- Java并发学习(一)
- 设计模式之抽象工厂模式
- 关于两个任意长度的数字相乘的代码设计(不使用BigDecimal的情况下)
- Python模拟登陆CSDN
- 顺序表——插入不重复元素
- 遥感图像波段运算:分段公式叶面积指数计算
- HTML表格
- Python学习:HTML表单
- Python中的多进程和多线程