笼统的划分,安卓中线程分为UI线程和工作线程,UI线程被称为主线程,主要负责更新UI,不适宜处理耗时的任务,否则会造成界面卡顿或ANR异常。所以耗时任务应放在工作线程中去处理,但是也不是多开工作线程就是好的,毕竟工作线程和UI线程也是竞争关系。
工作线程的集中创建方式如下:
1.直接new Thread或者复写Thread中的run方法,然后调用start()方法执行线程
Thread {
//执行线程耗时任务
}.start()//调用start开启线程
class MyThread : Thread() {
override fun run() {
//执行线程耗时任务
}
}
MyThread().start()
2.用AsyncTask,已被弃用
class MyAsyncTask : AsyncTask<String, Int, String>() {
override fun doInBackground(vararg params: String?): String {
//执行线程耗时任务
return "result"
}
override fun onProgressUpdate(vararg values: Int?) {
//update 进度
}
override fun onPostExecute(result: String?) {
//result
}
}
//开启多个任务是默认串行执行 此外AsyncTask.excute(runnable:Runnable)也是串行执行
MyAsyncTask().execute("params")
//接受一个线程池,开启多个任务是并发执行
//此外AsyncTask.THREAD_POOL_EXECUTOR.execute(runnable:Runnable)也是并发执行
MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "params")
3.用handler
class ThreadHandler(looper: Looper) : Handler(looper) {
override fun handleMessage(msg: Message) {
Log.i("tag","此打印运行在ht子线程中")
}
}
val ht = HandlerThread("current-thread")
ht.start()
//在主线程或者其他子线程拿到此handler对象即可向ht线程发送消息,消息由ThreadHandler的handleMessage处理
val handler = ThreadHandler(ht.looper)
handler.sendEmptyMessage(0)
//ht子线程会一直运行,适当时候手动停止
ht.quitSafely()
4.IntentService
class MyIntentService(name: String?) : IntentService(name) {
override fun onHandleIntent(intent: Intent?) {
TODO("Not yet implemented")
}
}
startService(Intent())
5.线程池
Executors.newSingleThreadExecutor()//线程数量为1的线程池
Executors.newCachedThreadPool()//线程可复用线程池
Executors.newFixedThreadPool(10)//线程数固定的线程池
Executors.newScheduledThreadPool(10)//可指定定时任务的线程池
线程的各种状态:
NEW :线程被创建,但还没有调用start方法开启时的状态
RUNNABLE:线程调用start后,运行中的状态
BLOCKED:运行中的线程被锁给阻塞住时的状态
WAITING:线程处于等待状态 ,例如被调用了wait()或joIn()方法的线程
TIME_WAITING:超时等待状态,指定特定时间后返回,例如被调用了wait(long)或sleep(long)方法的线程
TERMINATED:线程执行完毕,中止状态
例如
val obj = Object()
class R1 : Runnable {
override fun run() {
Log.i("tag", "r1 running") //log 1
synchronized(obj) {
obj.wait()
}
Log.i("tag", "r1 end")//log 2
}
}
class R2 : Runnable {
override fun run() {
Log.i("tag", "r2 running") //log 3
synchronized(obj) {
//notity并不会释放当前资源锁的持有,所以此线程执行完后才执行被notify的wait线程
obj.notify()
}
Log.i("tag", "r2 end") //log 4
}
}
Thread(R1()).start() //start-one
Thread(R2()).start() //start-two
//start-one和start-two谁先运行不一定,如果start-one先运行,则输出为log 1 -> 3 -> 4 -> 2
//如果start-two先运行,则输出为log 3 -> 4 -> 1 log 2没机会执行,此所谓假死
解决假死就需要保证wait先执行,notify后执行,提高优先级的方法只是提高概率,不会保证start-one一定先执行,所以用一个原子变量的方法来解决更合适
val obj = Object()
@Volatile//不可用于局部变量
var hasNotify = false
class R1 : Runnable {
override fun run() {
Log.i("tag", "r1 running") //log 1
synchronized(obj) {
if (!hasNotify) {
obj.wait()//为了以防万一,这里也可以使用wait(1000)来保证一定时间后自己苏醒
}
}
Log.i("tag", "r1 end")//log 2
}
}
class R2 : Runnable {
override fun run() {
Log.i("tag", "r2 running") //log 3
synchronized(obj) {
//notity并不会释放当前资源锁的持有,所以此线程执行完后才执行被notify的wait线程
obj.notify()
hasNotify = true
}
Log.i("tag", "r2 end") //log 4
}
}
Thread(R1()).start() //start-one
Thread(R2()).start() //start-two
//start-one和start-two谁先运行不一定,如果start-one先运行,则输出为log 1 -> 3 -> 4 -> 2
//如果start-two先运行,则输出为log 3 -> 4 -> 1 log 2没机会执行,此所谓假死
线程安全方式:
AtomicInteger系列原子类,synchronized关键字,ReentrantLock
val lock = ReentrantLock()
try {
lock.lock()
} finally {
lock.unlock()
}