1.直接使用线程池:
对线程池不熟悉的可以看我另外一篇博客。上一篇的代码这一篇也有用到。线程池简介
/**
* 串行执行多线程任务 第一种 使用线程池
*/
//任务队列。android 提供有:LinkedBlockingQueue ArrayQueue ArrayBlockQueue 区别自己百度吧。
LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);
//线程工厂
ThreadFactory threadFactory = new ThreadFactory(){
@Override
public Thread newThread(@NonNull Runnable r) {
return new Thread(r);
}
};
//设置一个核心线程数为1,最大线程数为5,任务队列最大容量为100,闲置关闭时间为1秒的线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 5, 1l, java.util.concurrent.TimeUnit.SECONDS, workQueue, threadFactory);
public void executeByExecutor(Runnable runnable){
threadPoolExecutor.execute(runnable);
}
<img src="https://upload-images.jianshu.io/upload_images/13400445-50bccacbeba69c7d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="500" height="313" align=center/>
任务升级:我有时想串行,有时想并行。
没必要创建两个线程池。我们直接用一个线程池就能实现。
public class MyQueueAndThreadPool {
private final ThreadPoolExecutor threadPoolExecutor;
private ArrayDeque<Runnable> mTasks;
private Runnable mActive;
public MyQueueAndThreadPool(){
mTasks = new ArrayDeque<>();
ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(@NonNull Runnable r) {
return new Thread(r);
}
};
;
threadPoolExecutor = new ThreadPoolExecutor(5, 10, 60, java.util.concurrent.TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(), threadFactory);
}
public void execute(final Runnable r){
mTasks.offer(new Runnable() {
@Override
public void run() {
r.run();
doOnNext();
}
});
//第一个进去,启动这个循环。
if(mActive == null){
doOnNext();
}
}
public void executeOnExecutor(Runnable r){
threadPoolExecutor.execute(r);
}
private void doOnNext(){
if((mActive = mTasks.poll())!=null){
threadPoolExecutor.execute(mActive);
};
}
}
//执行。
// executeByExecutor(runnable);
// executeByExecutor(runnable_2);
// executeByExecutor(runnable_3);
myQueueAndThreadPool.executeOnExecutor(runnable);
myQueueAndThreadPool.executeOnExecutor(runnable_2);
myQueueAndThreadPool.executeOnExecutor(runnable_3);
其实这里就是asyncTask的内部逻辑。只是asyncTask同时考虑了异常和线程同步的问题,我这里只是简单实现了一下原理。。。
3.使用wait和notify
public class ThreadSerialzetow {
public static void main(String[] args){
ThreadA threadA = new ThreadA();
ThreadB threadB = new ThreadB();
ThreadC threadC = new ThreadC();
threadA.add(threadC);
threadB.add(threadA);
threadC.add(threadB);
threadA.start();
threadB.start();
threadC.start();
}
static class ThreadA extends Thread{
public ThreadC threadc;
@Override
public void run() {
while (true){
synchronized(threadc){
synchronized(this){
System.out.println("我是A");
this.notify();
}
try {
threadc.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void add(ThreadC th){
threadc = th;
}
}
static class ThreadB extends Thread{
public ThreadA threada;
@Override
public void run() {
while(true){
synchronized(threada){
synchronized(this){
System.out.println("我是B");
this.notify();
}
try {
threada.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void add(ThreadA th){
threada = th;
}
}
static class ThreadC extends Thread{
public ThreadB threadb;
@Override
public void run() {
while(true){
synchronized(threadb){
synchronized(this){
System.out.println("我是C");
this.notify();
}
try {
threadb.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void add(ThreadB th){
threadb = th;
}
}
}
这段代码不是我写的。是在网上找的。运行起来可以实现a>b>c顺序无限执行,有时可能会死锁,有时会出现a>c>b然后转为a>b>c。其中玄妙自己体会吧。。