Android 多线程实际上就是java SE 中的多线程,为了方便使用,封闭了一些类,如:AsyncTask,HandlerThread等。
多线程的实现---Thread和Runnable
//Thread 实现
new Thread() {
@Override
public void run() {
super.run();
//耗时操作
}
};
//Runnable 实现
new Thread(new Runnable() {
@Override
public void run() {
//耗时操作
}
}).start();
其实Thread也是一个Runnable 因为它实现的Runnable接口
Thread 中的wait, sleep, join, yield
wait()
:进入等待池中同时失去同步锁,使用notify, notifyAll或指定睡眠时间唤醒。注意wiat, notify, notifyAll 都必须在synchronized block 中否则会抛异常。
seep()
:是Thread 的步态方法,使用线程休眠,因为是线程的步态方法,所以同步锁不会释放。
join()
:待目标线程执行完后再继续执行。
yield()
:让出执行权让其他线程执行。
wait()与sleep() 使用
线程启动后调用wait() 进行入等待状态,3秒后唤醒。
public void test2() {
Log.i(TAG, "主线程运行");
Thread thread = new WaitThread();
thread.start();
long startTime = System.currentTimeMillis();
try {
synchronized (mLock) {
Log.i(TAG, "主线程等待");
mLock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
Long endTime = System.currentTimeMillis();
Log.i(TAG, "等待时间 :" + (endTime - startTime));
}
//等待线程
class WaitThread extends Thread {
@Override
public void run() {
try {
synchronized (mLock) {
//休眠3秒后唤醒
Thread.sleep(3000L);
mLock.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
super.run();
}
}
运行结果 :

wait()与sleep() 使用
线程池
如果频繁创建线程new Thread(),不是个好办法,因为新建与销毁性能差,缺乏统一管理,占用过多系统资源容易导致死锁。
多线程优点:
- 重用存在的线程,减少开销。
- 有效控制最大并发线程数,提高系统资源的使用,避免堵塞。
- 提供定时执行,定期执行,单线程,并发数控制等功能 。
线程池都实现了ExecutorService接口,Android中最常见的四类具有不同特性的线程池分别为FixedThreadPool、CachedThreadPool、SingleThreadPool、ScheduleThreadExecutor.
-
FixedThreadPool
创建指定的线程数量
只有核心线程,并且数量固定的,也不会被回收,所有线程都活动时,因为队列没有限制大小,新任务会等待执行.
优点:更快的响应外界请求. -
SingleThreadPool
只有一个核心线程,确保所有的任务都在同一线程中按顺序完成.因此不需要处理线程同步的问题. -
CachedThreadPool
没有空线程时创建线程
只有非核心线程,最大线程数非常大,所有线程都活动时,会为新任务创建新线程,否则会利用空闲线程(60s空闲时间,过了就会被回收,所以线程池中有0个线程的可能)处理任务.
优点:任何任务都会被立即执行(任务队列SynchronousQueue相当于一个空集合);比较适合执行大量的耗时较少的任务. -
ScheduledThreadPool
核心线程数固定,非核心线程(闲着没活干会被立即回收)数没有限制.
优点:执行定时任务以及有固定周期的重复任务
FixedThreadPool 使用(指定创建固定的线程)
//固定线程宾的使用
public void fixedThreadPool(int size) throws ExecutionException, InterruptedException {
//创建固定数量的线程池
ExecutorService executorService = Executors.newFixedThreadPool(size);
for (int i = 0; i < MAX; i++) {
//提交任务
Future<Integer> task = executorService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Log.i(TAG, "当前线程:" + Thread.currentThread().getName());
return fibc(40);
}
});
//获取结果
Log.i(TAG, "第:" + i + " 计算结果: " + task.get());
}
}
//效率低下的斐波那契数,耗时操作
public int fibc(int num) {
if (num == 0) {
return 0;
}
if (num == 1) {
return 1;
}
return fibc(num - 1) +fibc(num - 2);
}
//调用,指定为3个线程
fixedThreadPool(3);
运行结果:

可以看出线程创建是3个,并且都是按顺序执行的
CachedThreadPool 使用
//cachedThreadPool使用
private void cachedThreadPool() {
//创建CachedThreadPool线程池
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < MAX; i++) {
//提交任务
Future task = executorService.submit(new Runnable() {
@Override
public void run() {
//获取结果
Log.i(TAG, "当前线程:" + Thread.currentThread().getName() + " 计算结果: " + fibc(20));
}
});
}
}
//调用
cachedThreadPool();
计算结果:

没有空线程时创建线程
ScheduledExecutorService 使用(定时任务线程池)
private void scheduledThreadPool() {
//创建定时线程池
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
//参数1延迟时间,参数2周期,参数3时间单位
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
//获取结果
Log.i(TAG, "当前线程:" + Thread.currentThread().getName() + " 计算结果: " + fibc(20));
}
}, 1, 2, TimeUnit.SECONDS);
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
//获取结果
Log.i(TAG, "22当前线程:" + Thread.currentThread().getName() + " 计算结果: " + fibc(30));
}
}, 1, 2, TimeUnit.SECONDS);
}
//调用
scheduledThreadPool();
运行结果:

网友评论