关于Java线程的补充说明:

一、关键字synchronized的多种作用
        1、作为关键代码段同步:synchronized修饰一个方法,可将这个方法内的所有代码变成关键代码段,任意时刻只能有一个线程访问到该关键代码段(进入这个方法内部),其它线程自动等待。如:
        public synchronized void readFileAfterWriteOnce(...)
       
         2、作为互斥量同步:synchronized配合任意对象,可将这个对象变为互斥量,当任意线程进入synchronized构成的临界区内后,只有一个线程允许访问被synchronized修饰的对象。如:已知对象Object obj
        synchronized(obj) {
                obj.doSomeThing();
        }
       
        3、作为信号量同步:synchronized配合任意对象的wait方法和notify方法,可将对象作为信号量,当任意线程进入synchronized构成的临界区内后,会被wait方法挂起,直到另一个同样进入该临界区的线程运行notify方法后得以继续执行。如:
        while (true) {
                synchronized(obj) {
                        obj.notify();
                        ...
                        obj.wait();
                }
        }       
        一进入临界区,线程就运行对象的notify方法,通知其它线程可以继续运行,当然,由于临界区的作用,其它线程即便可以得到运行时间也无法进入临界区,这时当前线程执行完业务代码后运行对象的wait方法将自身挂起,同时也放弃了对临界区的占用,其它线程此时得以进入临界区,反复上述过程。
        wait默认是无限等待的,但也可以用一个long类型作为参数强制其只等待规定时间,如果没有等到notify,可以采取进一步的措施。

二、线程的正统用法:
        Java的线程可以有多种启动方法,比如可以让当前类成为Thread类的子类,然后重写其run方法。但由于Java无法进行多继承,所以一旦继承了Thread类,将影响到这个类继承其它类。所以正统的方法是让线程实现Runnable接口。Thread类也是从这个接口派生出来的,所以Thread类可以通过一个继承自Runnable接口的任意类构造自身。比如:
        class TestThread implements Runnable {
                ...;
                public void run() {
                        ...;
                }
       
}
        启动线程时只需要使用如下代码:
        TestThread tt = new TestThread();
        Thread t = new Thread(tt);
        t.start();

       
三、杂项:
        Thread.join方法可以强制一个线程等待另一个线程结束后方能继续运行,该方法可以用一个long的参数指定等待多少时间后放弃等待。
        Thread.interrupt方法可以强制一个线程结束。
        每一个Thread对象都有一组属性,分别是:ID号,名字,状态。其中ID号为系统分配,表示该线程在线程内核对象链表中的索引,名字标志着一个线程,可以在构造函数中指定或者由系统分配,通过一个线程的名字可以获得它的内核对象的引用,从而构建一个同样的Thread对象。状态无非就是查看线程是否在运行,是否已结束,是否继续存活等基本状态,Thread类有一套方法可以获得线程的ID,名字和状态。
        Thread类还有一组静态方法,用于控制当前线程,包括可以获得当前线程的currentThread方法,挂起当前线程的yield方法,强迫当前线程休眠的sleep方法,holdsLock方法用于检查一个对象是否被当前线程当作线程锁使用等等。

四、注意事项;
        可以看出来,Java提供的同步方法和线程方法比较轻量级,很多功能都没有,当然可以通过编程技巧针对每个应用去完善这些功能,但带来了编程量和编程难度的增加。
        另外,Java的线程是没有返回值的,Java应该提供一个强制性接口允许一个线程取得另一个线程的退出码,从而判断另一个线程是否正常完成了工作,虽然可以自己编程来实现这个退出码,但是毕竟并不是所有的程序都是一个程序员来完成的,没有一个统一标准则很难在一个工程中进行协调,更不用提第三方开发的组件了。
         Sun不断的修正着Java线程,很多老的方法(比如一些挂起线程和杀死线程的方法)都不推荐使用了,这点要注意。