博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java多线程总结
阅读量:6814 次
发布时间:2019-06-26

本文共 4865 字,大约阅读时间需要 16 分钟。

hot3.png

在Java的线程编写,大部分可以用成熟的工具类来实现。

1.ThreadLocal(线程范围内的共享数据)

ThreadLocal
x = new ThreadLocal
();

一个线程有一个空间可以共享。可以利用泛型设计复杂的数据结构

也可以利用这个设计线程的单例模式

/** * @author wengwh * @Date 2014-8-4 */public class MyThreadScopeData {    private static ThreadLocal
map = new ThreadLocal
(); private MyThreadScopeData() { }; public static MyThreadScopeData getThreadInstance() { MyThreadScopeData instance = map.get(); if (instance == null) { instance = new MyThreadScopeData(); map.set(instance); } }}

2.线程池

jdk提供了几种类型的线程池,可以根据需要选择其中一种。

ExecutorService threadPool = Executors.newFixedThreadPool(3);threadPool.execute(new Runnable() {        @Override    public void run() {            }});

3.Callable与Future

Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的。

Callable要采用ExecutorService的submit方法提交,返回的future对象可以取消任务。

CompletionService用于提交一组Callable任务,其task方法返回已完成的一个Callable任务对应的Future对象。

Future
future = threadPool.submit(new Callable
() { public String call() { return "hello"; } });try { System.out.println(future.get());} catch (InterruptedException | ExecutionException e) { e.printStackTrace();}

4.Lock锁

比较简单的示例

Lock lock = new ReentrantLock();lock.lock();try{    for(int i=0;i<10;i++){        System.out.println(i);    }}finally{    lock.unlock();}

5.读写锁

读写锁就是一种,可以同时读,不能同时读写,写写

代码示例:

ReentrantReadWriteLock writeLock = new ReentrantReadWriteLock();writeLock.readLock().lock();writeLock.readLock().unlock();writeLock.writeLock().lock();writeLock.readLock().lock();writeLock.writeLock().unlock();writeLock.readLock().unlock();

6.Condition

Condition的功能类似在传统线程技术中的Object.wait和Object.notify的功能

可以通过定义2个condition对象来实现生产者模式

Lock lock = new ReentrantLock();Condition condition = lock.newCondition();lock.lock();condition.await();condition.signal();lock.unlock();

7.Semaphore

Semaphore可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如:实现一个文件允许的并发访问数。

Semaphore sp = new Semaphore(3);sp.acquire();获取一个信号sp.release();释放一个信号

8.CyclicBarrier

CyclicBarrier是要等到全部的线程都到达才会一起进行下去

例子:直接到有3个都到达了才会继续下一个

final CyclicBarrier cb = new CyclicBarrier(3);for(int i=0;i<3;i++){    Runnable runnable = new Runnable() {        @Override        public void run() {            // TODO Auto-generated method stub            try {                Thread.sleep((long)Math.random()*10000);                System.out.println(cb.getNumberWaiting());                cb.await();                System.out.println("end");            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            } catch (BrokenBarrierException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    };    Thread thread = new Thread(runnable);    thread.start();}

9.CountDownLatch(倒计时器)

cdOrder.countDown();计数器减一cdOrder.await();计数器为0时候触发

10.Exchanger(两个线程之间的数据交换)

final Exchanger
exchanger = new Exchanger<>();for(int i=0;i<2;i++){ Runnable runnable = new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { System.out.println("start-"+Thread.currentThread().getName()); System.out.println(exchanger.exchange(Thread.currentThread().getName())+Thread.currentThread().getName()); System.out.println("end-"+Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread thread = new Thread(runnable); thread.start();}

11.队列

队列是一种数据结构.它有两个基本操作:在队列尾部加人一个元素,和从队列头部移除一个元素就是说,队列以一种先进先出的方式管理数据。Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接口。Queue接口窄化 了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。BlockingQueue 继承了Queue接口。

几种阻塞队列:

LinkedBlockingQueue的容量默认是没有上限的(在不指定时容量为Integer.MAX_VALUE),也可以选择指定其最大容量,它是基于链表的队列,此队列按 FIFO(先进先出)排序元素。

ArrayBlockingQueue在构造时需要指定容量,并可以选择是否需要公平性(默认false),如果公平参数 被设置true,等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来达到这种公平性的:即等待时间最长的线程 会先操作)。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队列,此队列按 FIFO(先进先出)原则对元素进行排序。

PriorityBlockingQueue是一个带优先级的队列,而不是先进先出队列。元素按优先级 顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对PriorityQueue的再次包装,是基于堆数据结构 的,而PriorityQueue是没有容量限制的,与ArrayList一样,所以在优先阻塞队列上put时是不会受阻的,但是如果队列为空,取元素的操作take就会阻塞。另外,往入该队列中的元 素要具有比较能力。

DelayQueue(基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满,poll就以移除这个元素了。此队列不允许使用 null 元素。

12.同步集合

Collections工具类

注意:在集合的迭代过程中,不能对集合进行删除操作 这个时候可以用CopyOnWriteArrayList

转载于:https://my.oschina.net/u/1261308/blog/906747

你可能感兴趣的文章
《TCP IP 详解卷1:协议》阅读笔记 - 第十四章
查看>>
零跑C-more收获更多期待,而零跑S01还在追求更多的订单 | 2019 上海车展 ...
查看>>
彩铅,梦境
查看>>
中国存储芯片进入战略关键期
查看>>
rocketmq 同步双写
查看>>
张高兴的 Windows 10 IoT 开发笔记:部署 ASP.NET Core 2 应用
查看>>
装饰器
查看>>
Linux网卡名改eth0方法
查看>>
指针的意义和linux的内存回收艺术
查看>>
WP7实例篇之土豆搜索器(2)
查看>>
用SHELL脚本自动化安装Nagios服务器端和客户端的
查看>>
JAVA多线程之中断机制(如何处理中断?)
查看>>
vba 工作案例1
查看>>
利用Python了解微信通信机制,实现查询有多少好友删除你!!
查看>>
【mybatis深度历险系列】mybatis中的动态sql
查看>>
瑞典驻华参赞:智慧城市建设提升为国家战略
查看>>
淘富成真,硬件智能—— 硬件创新一站赋能平台
查看>>
网友神总结:我们继续用 XP 的十大理由
查看>>
2014年8月份国内主浏览器市场份额排行榜
查看>>
优云automation实践技巧:简单4步完成自动化构建与发布
查看>>