多线程并发库(一)
来源:互联网 发布:c语言点滴 epub 编辑:程序博客网 时间:2024/05/01 11:21
ThreadLocal
是线程局部变量。在多线程中,实现每个线程中变量的私有性。
例子一
在该例子中,在同一个线程中通过调用类A和类B的getData()方法获取的数据是一致的。
public class ThreadLocalTest {static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();public static void main(String[] args) { final ThreadLocalTest tlt = new ThreadLocalTest(); for(int i=0;i<3;i++){ new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(); threadLocal.set(data); System.out.println(Thread.currentThread().getName()+"==生成的数据是:"+data); tlt.new A().getData(); tlt.new B().getData(); } }).start(); }}class A{ public void getData(){ System.out.println(Thread.currentThread().getName()+"A:"+"取出的数据是:"+threadLocal.get()); }}class B{ public void getData(){ System.out.println(Thread.currentThread().getName()+"B:"+"取出的数据是:"+threadLocal.get()); }}
** }
结果:**
Thread-1==生成的数据是:-229198565Thread-2==生成的数据是:-1892334218Thread-0==生成的数据是:-1126013147Thread-0A:取出的数据是:-1126013147Thread-1A:取出的数据是:-229198565Thread-2A:取出的数据是:-1892334218Thread-1B:取出的数据是:-229198565Thread-2B:取出的数据是:-1892334218Thread-0B:取出的数据是:-1126013147
例子二
实现每个线程只拥有一个实例对象的写法。
public class ThreadLocalForObjTest {static ThreadLocal<Student> threadLocal = new ThreadLocal<>();public static void main(String[] args) { final ThreadLocalForObjTest tlt = new ThreadLocalForObjTest(); for(int i=0;i<3;i++){ new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(150); Student s = Student.getInstance(); s.setAge(data); s.setName("lzl"+data); threadLocal.set(s); System.out.println(Thread.currentThread().getName()+"==生成的数据是:"+data); tlt.new A().getData(); tlt.new B().getData(); } }).start(); }}class A{ public void getData(){ System.out.println(Thread.currentThread().getName()+"A:"+"取出的数据是:"+threadLocal.get().toString()); }}class B{ public void getData(){ System.out.println(Thread.currentThread().getName()+"B:"+"取出的数据是:"+threadLocal.get().toString()); }}}class Student{private String name;private int age;private static ThreadLocal<Student> map = new ThreadLocal<Student>();public static Student getInstance(){ Student instance = map.get(); if(instance ==null){ instance = new Student(); map.set(instance); System.out.println("======显示次数========"); } return instance;}public String getName() { return name;}public void setName(String name) { this.name = name;}public int getAge() { return age;}public void setAge(int age) { this.age = age;}@Overridepublic String toString() { return "Student [name=" + name + ", age=" + age + "]";}}
结果
三个线程,创建了三个实例对象。并且保证单个线程中的数据是私有的。
======显示次数==============显示次数==============显示次数========Thread-0==生成的数据是:81Thread-1==生成的数据是:67Thread-2==生成的数据是:81Thread-2A:取出的数据是:Student [name=lzl81, age=81]Thread-0A:取出的数据是:Student [name=lzl81, age=81]Thread-1A:取出的数据是:Student [name=lzl67, age=67]Thread-1B:取出的数据是:Student [name=lzl67, age=67]Thread-0B:取出的数据是:Student [name=lzl81, age=81]Thread-2B:取出的数据是:Student [name=lzl81, age=81]
多线程中共享数据
如果代码块执行的逻辑相同,可以在一个继承Runnable的类中实现数据的共享。
两个线程之间共享了count数据public class MultiThreadShareData {public static void main(String[] args) { MyRunnable mr = new MyRunnable(); new Thread(mr).start(); new Thread(mr).start();}static class MyRunnable implements Runnable{ private int count=5; @Override public void run() { while(true){ System.out.println("线程名:"+Thread.currentThread().getName()+" count="+count); if(count<1){ break; } dec(); } } private synchronized int dec(){ count--; return count; }}}
结果:
线程名:Thread-0 count=5线程名:Thread-1 count=5线程名:Thread-0 count=4线程名:Thread-1 count=3线程名:Thread-1 count=1线程名:Thread-0 count=2线程名:Thread-1 count=0
如果代码块不同,就将数据封装到同一个对象中,将这个对象逐一传递给每个Runnable对象。
两个线程之间共享了data数据public class MultiThreadShareData2 {public static void main(String[] args) { new MultiThreadShareData2().init();}private void init(){ new Thread(new DecRunnable(this)).start(); new Thread(new IncRunnable(this)).start();}int data=10;private synchronized void dec(){data--; System.out.println(Thread.currentThread().getName()+" data Dec="+data);}private synchronized void inc(){ data++; System.out.println(Thread.currentThread().getName()+" data Inc="+data);}static class DecRunnable implements Runnable{ private MultiThreadShareData2 data; public DecRunnable(MultiThreadShareData2 data2){ this.data = data2; } @Override public void run() { while(true){ data.dec(); } }}static class IncRunnable implements Runnable{ private MultiThreadShareData2 data; public IncRunnable(MultiThreadShareData2 data2){ this.data = data2; } @Override public void run() { while(true){ data.inc(); } }}}
Executors的应用
创建固定大小的线程池
ExecutorService fixedThreadPools = Executors.newFixedThreadPool(5);
创建缓存线程池
ExecutorService threadPools = (ExecutorService) Executors.newCachedThreadPool();
创建单一线程池(保证内存中一直有一条线程)
ExecutorService sigleThreadPools = Executors.newSingleThreadExecutor();
线程池启动定时器
ScheduledExecutorService threadPools = (ScheduledExecutorService) Executors.newScheduledThreadPool(3); //创建一个计时器的线程 threadPools.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("hhh"); } }, 2, 2, TimeUnit.SECONDS);}
例子:
public class ExecutorsTest {public static void main(String[] args) { ExecutorService threadPools = (ExecutorService) Executors.newCachedThreadPool();//创建缓存线程池。线程的大小没有固定 ExecutorService fixedThreadPools = Executors.newFixedThreadPool(5);//创建固定大小的线程池 ExecutorService sigleThreadPools = Executors.newSingleThreadExecutor();//创建 for(int i=0;i<10;i++){ final int task = i; fixedThreadPools.execute(new Runnable() { @Override public void run() { for(int i=0;i<10;i++){ System.out.println("线程名:"+Thread.currentThread().getName()+" 循环了"+i+"次,第"+task+"任务"); } } }); } System.out.println("循环结束..."); new ExecutorsTest().hh();}
Callable和Future
通过Executors的submit方法获取线程中返回的结果。
public class CallableAndFuture {public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2000); return "Hello Thread!"; } }; Future<String> future = executorService.submit(callable); System.out.println("等待结果..."); try { System.out.println("结果是:"+future.get(1,TimeUnit.SECONDS)); //1s后没有拿到结果,就抛错! } catch (InterruptedException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }}}
CompletionService提交多组数据
private void futureTest2(){ ExecutorService executorService = Executors.newFixedThreadPool(5); CompletionService<Integer> completionService = new ExecutorCompletionService(executorService); for(int i=0;i<10;i++){ final int task=i; completionService.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { Thread.sleep(new Random().nextInt(5000)); return task; } }); } for(int i=0;i<10;i++){ try { System.out.println("结果是:"+completionService.take().get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }}
1 0
- 多线程并发库(一)
- 多线程并发库_<一>
- 多线程并发问题(一)
- 多线程并发知识点(一)
- 并发与多线程(一)
- JAVA多线程并发库高级应用 (一)
- 并发编程(一):多线程基础知识
- 多线程&并发(一)
- 多线程并发学习(一)
- 多线程并发编程(一):传统多线程实现方式
- 【JAVA并发学习一】并发和多线程
- Java 并发 (多线程) 讲解<一>
- java多线程与高并发库应用(一)线程基础概念
- C++11并发编程(一)——初始C++11多线程库
- java多线程并发(一)(线程基础)
- java多线程和并发编程(一)--- java 线程小结
- 关于Java多线程和并发运行的学习(一)
- Java多线程与并发编程总结(一)
- Linux重要命令行
- unity3D 完美解决 全屏输入法问题
- 继承中的方法重写
- 事务的四大特性
- struts的相关配置
- 多线程并发库(一)
- IIS7 / IIS7.5 URL 重写 HTTP 重定向到 HTTPS
- 初始化
- 31.Next Permutation
- 毕业论文出炉记录(纯纯的菜鸟文)
- 针对魔兽争霸3“萝莉”病毒的扫描工具开发
- linux 环境变量设置(临时 + 永久)
- recycleView基本知识
- Android 属性动画探究(二)——TypeEvaluator解析与自定义