Java中的多线程是一种抢占机制而不是分时机制。抢占机制指的是有多个线程处于可运行状态,但是只允许一个线程在运行,他们通过竞争的方式抢占CPU。这就有了线程间的通信,也就是等待唤醒机制。本帖只分析Thread类中的练习过程中遇到的方法。
----------------------------------------------------------------
一.为什么操作线程的这些方法定义在Object类中。
用于线程间通信的方法:
void notify();void notifyAll();唤醒在此对象监视器上等待的单个、所有线程。
void wait();void wait(long timeout);
void wait(long timeout, int nanos);在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待的三个重载方法。
因为这些方法存在于同步中,所以使用这些方法时都要标示所属的同步的锁。锁可以是任意对象,能被任意对象调用的方法一定是定义在Object类中。
-----------------------------------------------------------------
二.继承Thread类开启线程方法
1,定义类继承Thread。
2,复写Thread类中的run方法(将自定义代码存储在run方法。让线程运行)。
3,调用线程的start方法。
这里复写的是run()方法,但调用start()方法开启线程。run()方法可以自定义需要多线程运行的代码段。查看api的start方法描述,start除了开启了线程,并且调用了该线程中的run()方法。此处需要注意的是,复写run()方法在该线程的start()方法被调用后,虚拟机会自动调用run方法来执行任务;但是重载的run()方法和普通方法一样,并不会被start()方法调用。比如:
*********代码段一- public class MyThread extends Thread
- {
- public void run()
- {
- System.out.println("run........");
- }
- public void run(int num)
- {
- num = 11;
- System.out.println("run(int num).......");
- }
- }
复制代码 -----------------------------------------------------------------
三.如果在Thread子类里覆盖了run方法并编写需要运行内容,同时,也通过
Thread的构造函数传递一个Runnable实例对象,那么,线程运行时,执行的是
Thread子类的run()代码还是Runnable对象的run()?
如*********代码段二:- /**
- Thread子类里覆盖了run方法,且
- Thread的构造函数传递一个Runnable实例对象。分别有自己的run方法体。
- */
- class Noname1
- {
- public static void main(String args[])
- {
- new Thread(
- new Runnable()
- {
- public void run()
- {
- System.out.println("Runnable run......");
- }
- })
- {
- public void run()
- {
- System.out.println("Thread子类 run........");
- }
- }.start();
- }
- }
复制代码 运行结果如图:
但为什么结果是这样呢?
查看Thread类的run()方法的源代码,可以看到其实这两种方式都是在调用Thread对象的run方法。如果Thread类的run方法没有被覆盖,并且为该Thread对象设置了一个Runanble对象,该run方法会调用Runnable对象的run方法。
-----------------------------------------------------------------
四.如何正确停止线程。
查看api可以发现。destroy()以及stop()等一些原来用于强停或者破坏线程的方法因为存在安全问题都已过时。所以,停止线程的总的原则是run()方法结束。开启多个线程,运行代码通常是循环结构。只要控制好循环,就可以让run方法结束,run方法结束也就是线程结束。特殊情况是,当线程处于冻结状态,就不会读取循环的标记,那么线程就不会结束。当没有指定的方式让冻结的线程恢复到运行状态是,这时需要对冻结进行清除。强制让线程恢复到运行状态中来。使用Thread类中的interrupt方法,这样就可以操作标记让线程结束。
------------------------------------------------------------------
五.其它方法。
currentThread();获取当前线程对象的引用。
getName();返回该线程名字。
join();当A线程执行到了B线程的.join()方法时,A就会等待。等B线程都执行完,A才会执行。
toString();返回该线程的字符串表示形式,包括线程名称、优先级和线程组。
更多方法参照api。
|
|