首页 › 程序设计 › java

java多线程和android平台下的多线程

泡在网上的日子 / 文 发表于2013-08-29 18:36 次阅读 java,多线程

一、多线程的概念

多线程即是进程的多个执行路径,但并不能理解为这几个路径是同时执行的。在单cpu下应该是根据优先级调度法则轮流给这些个线程的执行时间片。

二、Java中的多线程

1)、如何创建一个线程

        两种方式,实现Runnable接口和继承Thread类。一般建议使用Runnable接口。

2)、join、yield、sleep关键字的含义

        Join即是将某一线程插入到当前线程中执行;yield使得与当前正在执行的线程有相同优先级的其它线程有执行的机会;sleep使当前线程休眠一段时间,可使得优先级低的线程有执行的机会。

3)、线程的优先级

        Java中可以设定线程的优先级,其线程调度策略是基于优先级的抢占式调度法则,即优先级高的线程可以抢占优先级低的线程的cpu执行段,当优先级高的线程执行完毕后,优先级低的线程才有执行的机会。

4)、死锁

        死锁的产生的基本原因是:线程1拿到了A资源的锁并等待B资源的锁,线程2拿到了B资源的锁并等待A资源的锁,由于两个线程互不释放各自的资源,导致两个线程均不能执行下去。

        Java中并没有死锁的专门检测、避免机制,需要在程序中实现。通常的做法是:1、在全局中定义获得锁的顺序,线程按照顺序获得资源锁,反向释放资源锁。2、线程要么一次性获得所有的锁,要么不获得任何锁。

三、线程同步(生产者和消费者问题)

多线程环境下,一个资源可能有多个线程在使用,产生了线程同步的问题。Java中用synchronized关键字对对象或者方法进行同步。该关键字的含义是对对象或者方法进行加锁以保证在同一时间段只有一个线程使用。Wait是当某个线程需要获得对象资源时而其它线程正在使用时则等待,此时该线程会进入该对象的线程等待池。notify(notifyall)关键字是唤醒某个对象资源线程等待池的线程,表明已有线程释放了该资源。

一个经典的问题是生产者和消费者的问题,在附录中有测试demo

四、线程池的概念和用法

在JDK1.5以后,java的API中有了线程池,好像有多种类型的线程池,目前只用过ThreadPoolExecutor(int corePoolSize,int maximumPoolSize, long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler),其中corePoolSize为核心线程数(即线程池中的长工)、maximumPoolSize为最大线程数(长工+短工),keepAliveTime为短工无任务时的存活时间,unit为时间单位,workQueue为任务队列,Handler为拒绝任务的处理器。关于详细的线程池的讲解不在这里一一展开。

五、Android下的多线程

在android中每一个APP应用是在一个单独的dalvik虚拟机单一的linux进程中,每一个应用有一个主线程(main thread)这个主线程负责分发按键的响应等与用户交互的事件响应,在这个主线程内不能有太长时间的阻塞,线程阻塞超过5秒后就会报程序无响应的错误。因此一些复杂的、耗时的操作必须开启新的线程去操作,但是在android的框架中UI元素是必须在主线程才能更新的,所以在后台的复杂逻辑完成后,要更新与用户交互的UI元素又必须回到主线程中。在android中有两个重要的工具可以利用,Handler和AsyncTask。

Handler可以处理一些消息和将一些Runnable借口运行在其当前的线程中。目前应用的最多的是主线程创建一个Handler实例,并将该实例传递给后台运行的线程,后台的线程完成其工作后,使用该Handler发送一个message,这时在主线程中接受到该消息,然后进行一些UI的更新。至于参数的传递等细节的问题,可以查阅Message类的说明,在这里就不一一展开。

AsyncTask异步任务是android专门设计来解决后台线程完成后更新主线程中的UI元素的一个类。其三个泛型参数为Param、Process、Result。Param为传入参数、Process为进度、Result为后台任务完成后传递到主线程中的参数。该类中有四个可以重载的方法:

1、  onPreExecute:在后台逻辑执行前需要的准备工作在这里完成。UI线程【即主线程】在doInBackground前调用该方法。【注意该方法是执行在UI线程中的】

2、  doInBackground:后台线程调用该方法完成复杂耗时的逻辑,可以通过publishProgress方法来更新实时的任务进度到UI,publishProgress需要自己实现

3、  onProgressUpdate:当publishProgress被调用后,UI线程调用该方法更新UI。

4、  onPostExecute:当doInBackground完成后,将Result传递到该方法,UI线程调用。


收藏 赞 (0) 踩 (1)
上一篇: Java 异常处理的最佳实践Best Practices for Exception Handling
译者注 :这是一篇 2003 年的文章,因为时间久远,可能有些观点已经过时,但里面讨论的大部分方法如今仍能适用。如若有其他好的错误处理的方法,欢迎留言。 异常处理的关键就在于知道何时处理异常以及如何使用异常。这篇文章,我会提到一些最佳的异常处理方
下一篇:java笔试字符串转换:大写变小写小写变大写数字不变
字符串转换在笔试中经常遇到 /** * * @author zb *转换字符串,大写变小写,小写变大写,数字不变,其他变为* */public class Transfer{ public static void main(String[] args){ String str = "ABC123abcfadfjbJBHJHJDsa"; StringBuffer sb = new StringBu