------- android培训、java培训、期待与您交流! ----------
线程,指的是在程序执行过程中沿一条线索逐条语句按顺序执行的流程。main函数就是一个线程,叫做主线程。在多线程开发过程中,随着主函数的进行,可以随时开启一个独立执行的线程。多线程可同时执行,同时执行的本质可以是CPU多核同时执行多个任务,也可以是CPU内核在多任务间的飞速切换。在Java中,线程被预定义包装成了java类库中的类,该类是java.lang.Thread,Thread实现Runnable接口(run()方法),当线程启动时,执行的就是run()方法。
线程类必须是Thread类或其子类。run()方法中的内容,是自定义线程类最核心的内容,可以在继承自Thread的类中重写run()方法,也可以通过定制一个实现了Runnable接口的类(实现其run()方法),再通过在Thread构造方法中传入一个该类对象的方式建立自定义线程。
线程的状态:
在Java当中,线程通常都有五种状态,创建、就绪、运行、阻塞和死亡。
第一是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。
第二是就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。
第五是死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。
并发编程引发的问题是不确定的,有可能在程序检测时并未发生,在客户使用的过程中却出现。Java使用并发系统会共享诸如内存和I/O这样的资源,因此编写多线程程序最基本的困难在于在协调不同线程驱动的任务之间对这些资源的使用,以使得这些资源不会同时被多个任务访问。
并发需要付出代价,包含复杂性代价,但是这些代价与程序设计、资源负载均衡以及用户使用方便方面的改进相比,就显得微不足道了。
Executor:
Java SE5对java.util.concurren包中的执行器(Executor)能管理Thread对象,简化编程。
将Runnable类对象作为参数传入Executor对象的execute(Runnable r)方法可以启动新的线程执行此Runnable中的run()方法。
ExectorService exec=Executors.newCachedThreadPool();
ExectorService exec=Executors.newFixedThreadPool();
ExectorService exec=Executors.newSingleThreadExecutor();
exec.execute(r);
将Callable类(具有返回值的泛型类,其call()方法相当于Runnable类的run()方法,能产生线程;Callable
Callable c=new Callable(){
public T call(){
.....
return (T)t;
}
};
Future fu=exec.submit(c);
if(fu.isDone)
T t=fu.get();
优先级:所有线程都应该以默认的优先级运行,试图操纵线程优先级通过是种错误。JDK有10个优先级。
让步:
Thread的yield()方法会给线程调度器一个暗示:本线程的工作可以暂停一下了,让别的线程继续执行。但这只是一种暗示,没有任何机制保证它一定被线程调度器采纳。
后台线程:
当所有非后台线程执行结束后,程序会自动终止所有未执行完毕的后台程序。Thread的setDaemon(boolean b)和isDaemon()可以用来设置和判断线程的后台性。
由后台线程创建的线程自动被设置成后台线程。
后台线程在被迫终止时,其中的finally子句不会得到执行。
synchronized(obj)//obj是锁
{
.....
代码块
.....
}
使用同一个对象作为锁的同步代码块之间也是同步的。