子线程启动第一种

public class ThreadB implements Runnable {
    @Override
    public void run() {
    }
}
//mainactivity里
        new Thread(new ThreadB()).start();

子线程启动第二种

new Thread(new Runnable() {
            @Override
            public void run() {
                
            }
        }).start();

线程通信

looper默认存在于主线程中,在子线程和主线程通信时,子线程通过主线程中的handler发送消息给主线程的messageQueen消息队列,通过主线程中的looper取出,在handleMessage方法里可以使用【handleMessage运行在主线程中】,那么子线程间怎么通信 子线程没有looper

public class ThreadA implements Runnable {
    private Handler handler;

    public Handler getHandler() {
        return handler;
    }

    @Override
    public void run() {
        Looper.prepare();
        handler = new Handler() {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                //接受信息
                if (msg.what == 1) {
                    Log.i("tag", "handleMessage: 信息");
                }
            }
        };
        Looper.loop();
    }
}

三个线程输出ABC

ublic class RunThread implements Runnable {
    private String name;
    private Object pre;
    private Object self;

    public RunThread() {
    }

    public RunThread(String name, Object pre, Object self) {
        this.name = name;
        this.pre = pre;
        this.self = self;
    }

    @Override
    public void run() {
        int count = 5;
        while(count > 0){
        //同步
            synchronized(pre){
                synchronized(self){
                    count--;
                    Log.i("TAG", "run: "+name);
                    //唤醒
                    self.notify();
                }
                try {
                //等待
                    pre.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}


main:
        Object a = new Object();
        Object b = new Object();
        Object c = new Object();
        new Thread(new RunThread("A",c,a)).start();
        new Thread(new RunThread("B",a,b)).start();
        new Thread(new RunThread("C",b,c)).start();

线程池

  1. Executors.newCachedThreadPool()
    线程数量无限线程池
    首先会按照需要创建足够多的线程来执行任务(Task)。随着程序执行的过程,有的线程执行完了任务,可以被重新循环使用时,才不再创建新的线程来执行任务

2.Executors.newFixedThreadPool
线程数量固定线程池
一个优先固定数目的线程来处理若干数目的任务。规定数目的线程处理所有任务,一旦有线程处理完了任务就会被用来处理新的任务

3.Executors.newSingleThreadExecutor()
单一线程线程池
这个就是创建只能运行一条线程的线程池。它能保证线程的先后顺序执行,并且能保证一条线程执行完成后才开启另一条新的线程

4.Executors.newScheduledThreadPool
这是一个计划线程池类,它能设置线程执行的先后间隔及执行时间等,功能比上面的三个强大了一些。

提交任务方式

1.submit()
将线程放入线程池中,除了使用execute,也可以使用submit,它们两个的区别是一个使用有返回值,一个没有返回值。submit的方法很适应于生产者-消费者模式,通过和Future结合一起使用,可以起到如果线程没有返回结果,就阻塞当前线程等待线程 池结果返回。

2.execute()

结束任务

1.shutdown()
通常放在execute后面。如果调用 了这个方法,一方面,表明当前线程池已不再接收新添加的线程,新添加的线程会被拒绝执行。另一方面,表明当所有线程执行完毕时,回收线程池的资源。注意,它不会马上关闭线程池!

2.shutdownNow()
不管当前有没有线程在执行,马上关闭线程池!这个方法要小心使用,要不可能会引起系统数据异常!

线程池参数

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
corePoolSize:最大的核心线程数
maximumPoolSize:最大线程数量
maximumPoolSize - corePoolSize:非核心线程数量
keepAliveTime:非核心线程销毁时间
unit:时间单位
workQueue:任务队列