子线程启动第一种
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();
线程池
- 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:任务队列