安卓中的线程

笼统的划分,安卓中线程分为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()
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值