线程 又称"执行上下文"
线程有起点,终点,顺序,但不能单独运行,依赖于程序
有两种方法可以创建多线程的类
(1)派生Thread类的子类,Thread类在java.lang中定义
(2)实现Runnable接口,该接口中有一个run方法.Runnable接口也是在java.lang中定义
第二种方法主要用于要编写多线程的类需要从其它类中派生,出于java不能支持类的多继续的特性来考虑.
有关线程的几个重要概念:线程体,线程状态,ThreadGroup类
线程体:
线程体在run()方法中编写.
可以通过重要Thread中的run()方法或者实现Runnable接口中的Run方法.
线程的状态:
线程有四个状态
(1)新线程态
使用new运算符创建了一个Thread,并且在未调用start()方法之前
此时,线程只是空的对象,系统未分配任何系统资源.
可用stop()把新线程变为死亡态
(2)可运行态
调用了start(),线程进入可运行态.
此时,线程获得了必要的系统资源,并调用已经实现的run()方法.
此时,线程处于就绪状态,只等待处理器就可以运行了
(3)不可运行态
当调用了suspend()[挂起]方法,sleep()方法,用wait()方法等候一个条件变量或被IO阻塞,线程就可以从运行态变为不可运行态.
要重返可运行态,必须消除原来的不可运行原因:
suspend()挂起的线程再调用resume()[重新开始,恢复]
sleep()时间已经结束
等候的条件变量的拥有对象调用了notify()或notifyAll()方法
(4)死亡态
线程可以自然死亡,如它的run()方法正常退出运行.
也可以被杀死,调用stop()方法.该方法将抛出一个ThreadDeath对象给线程,线程接收到对象后才死亡.
Thread有一个isAlive()方法.当线程处理第二第三种状态时,返回true,另外两种返回false.
线程优先级
固定优先级调用,选择各可运行态的线程中优先级别最高的先运行,同级线程则排队执行.
新进入可运行态的线程若优先级高也可抢先获得运行权.
线程默认的优先级是继承创建它的线程而来的,可调用实现了Thread类的setPriority()方法修改.
一个线程调用yield()方法可以放弃CPU,但当其它的优先级别都比本线程低时,该方法无效.
Daemon[守护进程,后台程序]线程
该线程为同一进程中的其他线程或对象提供服务.
要定义一个线程为Daemon线程,要调用setDaemon(true)方法,可以通过isDaemon()方法来判断一个线程是否为Daemon.
线程组
由java.lang中的ThreadGroup类来实现
提供一种机制将多个线程收集成一个对象,在组中一齐处理.如调用一个方法挂起所有组中的线程
要加入某个线程组,需要在创建线程时的构造方法中进行指定.
未指明线程组的,默认放在创建它的线程的同一组中,即当前线程组.
对应于应用程序application,其当前线程组是一个叫main的线程组.
通过getThreadGroup()方法可以查明当前所属线程组
太晚了,未完待续...
ThreadGroup类
ThreadGroup中可以包含其它的ThreadGroup类,形成树状结构.
它提供一组方法管理一列线程,其它对象可以访问线程列表.
activeCount()可以获得组中的线程数.
enumerate()方法可以枚举组中的线程和其他线程组.
ThreadGroup类中有一些方法允许修改组中所有线程的当前状态.如resume(),stop(),suspend().这些方法会改变组中每个线程和子组中所有线程的状态.
同步与锁定
java语言从最基本的Object类开如就提供也实现线程同步的机制,如有notify(),notifyAll(),wait()这三个方法,它与通过调用synchronized方法进行监视,锁定对象,保证同一时刻只有一个线程可以取用这个对象(资源)
监视器:
多个线程异步地执行,试图同时访问一个对象,因些出现错结果,这种叫竞争条件问题.
监视器结合条件变量和锁定数据的功能,并锁的线程进行监视器之后呢,其它线程不能进入,直到被锁的线程退出监视器.
程序中能使并行线程访问共同数据对象的代码段称为关键部分,用synchronized关键字进行标记.
标记在方法上,该方法被称了同步方法,其锁定的是一个对象.
如果该方法是一静态方法,则锁定的是一个类.
一个同步方法对应有一个监视器,当一对象调用一同步方法时,就要先获得监视器,然后给对象加上锁,否则,只是等待锁被释放.
wait()方法:
已知该方法让当前线程进入不可运行态,等待某种条件的改变,线程将持续等待到其它线程调用notify()和notifyAll()方法来通知它.
当线程调用wait时,会自动释放监视器,当退出等待状态时,重新获得监视器.
notify()和notifyAll()方法:
notify()唤醒一个调用了当前对象的wait()方法而进入等待状态的线程,但并唤醒的线程并没有马上运行,它必须等到时当前线程退出sysnchronized块,释放了对象锁之后,被唤醒的线程才能有机会获得锁并开始运行.
关于同步与锁定的一般使用形式如下:
public class Test { public synchronized void go() { while(条件!=true) wait(); 逻辑处理; notify(); } }
死锁(DeadLock):
当发生死锁时,可以向一个线程抛出一个ThreadDeath对象杀死该进程.
调用wait()后,会释放监视器,让其它线程获得运行机会,避免死锁.