Java线程总结
来源:互联网 发布:淘宝三星手机官网 编辑:程序博客网 时间:2024/06/08 08:18
一、线程的创建
1、继承Thread类,重写run方法
优点:简单。缺点、;已经继承Thread类,不能再继承其他的类,不能共享实例变量。
2、实现Runnable接口,重写run方法。这种情况,多个线程可以共享Runnable实例变量。
3、使用Callable和Future创建线程,实现Callable接口。
第一步:
重写call方法,作为线程执行体,有返回值。
第二步:
创建Callable实例。
第三步:
创建FureTask实例,包装Callable对象,并封装Callable对象call方法的返回值。FutureTask实现Future接口,可以通过get方法获取call方法的返回值,调用改方法,导致程序阻塞,必须等到子线程结束才可以拿到返回值。isDone方法,如果Callable已经完成,返回true。可以使用ExecutorService。submit方法传入Callable实例,返回一个Future对象。
二、控制线程
1、join
在A线程的执行过程中,调用B线程的join方法,A线程将被阻塞,直到B线程执行完成。
2、线程让步yield
将线程转到就绪状态,让线程调度器重新调度一次(可能有重新转入的运行状态)
3、线程睡眠 sleep
调用该方法的线程进入阻塞状态,是调度器可以切换到其他线程。
三、线程池
1、调用Executors工具类产生线程池,一般有三种类型的线程池。
CachedThreadPool:创建一个具有缓存功能,创建于所需数量相同的线程,在回收旧线程时停止创建新线程。
FixedThreadPool:一次性分配固定数量的线程。
SingleThreadExecutor,创建只有一个线程的线程池,如果有多个人防,按提交顺序执行。
2、ExecutorService:调用submit方法,将Runnable或者Callable对象提交到线程池,返回null或者Future对象。调用shutdown方法,线程池不在接受新的任务,原来的任务仍然执行。调用shutdownNow方法,会停止所有正在执行的任务。
四、wait和notify
/** * 使用同步代码块 * * @param task */ private void addTaskToService(Task task) { synchronized (mObject) { if (mTaskService == null) { return; } while (mTaskService.getWaitingCount() >= QUEUE_LIMIT) { try { Log.i(TAG, "addTaskToService: wait " + task.getId()); mObject.wait(); } catch (InterruptedException ex) { } } Log.i(TAG, "addTaskToService Id: " + task.getId()); mTaskService.addTask(task); } }任务完成,通知添加任务的线程:
synchronized (mObject) { mObject.notifyAll(); Log.i(TAG, "onTaskDone notifyAll: " + task.getId()); }
五、Condition控制线程通信
对象使用Lock保证同步时,Java提供了一个Condition类保持协调。Condition实例绑定在一个Lock实例,调用Lock对象的newCondition方法可以得到Condition实例
/** * 使用对象锁 * * @param task */ private void addTaskToService2(Task task) { mLock.lock(); if (mTaskService == null) { return; } try { while (mTaskService.getWaitingCount() >= QUEUE_LIMIT) { Log.i(TAG, "addTaskToService: wait " + task.getId()); mCondition.await(); } Log.i(TAG, "addTaskToService Id: " + task.getId()); mTaskService.addTask(task); } catch (InterruptedException e) { } finally { mLock.unlock(); } }
任务完成,通知线程继续往里面添加:
mLock.lock(); mCondition.signalAll(); Log.i(TAG, "onTaskDone signal(): " + task.getId()); mLock.unlock();
六、阻塞队列控制线程通信
BlockingQueue接口用来做为线程同步的工具,当向BlockingQueue添加任务,如果该队列已满,则线程被阻塞。当从BlockingQueue取出任务时,如果队列已空,则线程被阻塞。
常用的两种ArrayBlockingQueue,和LinkedBlockingQueue,可以用来控制线程池,任务的分发往队列里面添加任务使用:put,当任务完成时,使用remove。
新建一个阻塞队列,限制任务数为5:
private BlockingQueue<Task> mBlockingQueue = new ArrayBlockingQueue(5);往BlockingQueue里面添加任务:
/** * 使用阻塞队列 * * @param task */ private void addTaskToBlock(Task task) { if (mTaskService == null) { return; } try { mBlockingQueue.put(task); Log.i(TAG, "mBlockingQueue " + task.getId()); } catch (InterruptedException e) { e.printStackTrace(); } Log.i(TAG, "addTaskToService Id: " + task.getId()); mTaskService.addTask(task); }任务完成,BlockingQueue取出:
try { mBlockingQueue.take(); } catch (InterruptedException e) { e.printStackTrace(); }
- Java线程总结
- Java线程总结
- Java线程总结
- java线程学习总结
- 【转】Java线程总结
- Java语法总结 - 线程
- Java线程总结
- Java线程总结
- Java线程总结
- Java线程总结
- Java语法总结 - 线程
- Java线程:大总结
- Java线程:大总结
- Java线程总结
- java线程安全总结
- Java线程总结
- java线程安全总结
- Java线程总结
- cocos2d::DrawPrimitives和DrawNode分别实现画板功能
- 使用ViewPager循环滑动时注意的问题
- 布局管理器之CardLayout(卡片布局管理器)
- acm算法之树状数组
- Docker Command List
- Java线程总结
- 今年暑假不AC
- JPA JPQL 查询、排序.....
- log4cplus学习指南(转)
- Android---40---实现XMl文件的序列化与解析
- 黑马程序员---Objective-C @property和@synthesize
- 技术路线的核心竞争力
- 基于Apache Mahout和Elasticsearch推荐系统介绍
- acm算法之三大背包问题