- 进程(Process)是计算机中程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的 基本单位,是操作系统结构的基础。
- 线程就是轻量级的进程,是程序执行的最小单位。使用多线程而不是用多进程去 进行并发程序的设计,是因为线程间的切换和调度的成本远远小于进程。
线程状态图
NEW表示刚刚创建的线程,这种线程还没开始执行。等到线程的start()方法调用时,才表示线程开始执行。当线程执行时,处于RUNNABLE状态,表示线程所需的一切资源都已准备好了。如果线程的在执行的过程中遇到synchronized同步块,就会进入BLOCKED阻塞状态,这时线程会暂停执行,直到获得请求的锁。WATING和TIMED_WATING都表示等待状态,他们的区别是WATING会进入一个无时间限制的等待,TIMED_WATING会进行一个有时限的等待。比如,通过wait()方法等待的线程在等待notify()方法,而通过join()方法等待的线程则会等待目标线程的终止,一旦等到了期望的事件,线程就会再次执行,进入RUNNABLE状态。当线程执行完毕后,则进入TERMINATED状态,表示结束。
- 终止线程 为什么stop()被废弃而不推荐使用呢?原因是stop()方法太过暴力,强行把执行到一半的线程终止,可能会引起一些数据不一致的问题。Thread.stop()方法在结束线程时,会直接终止线程,并且会立即释放这个线程锁持有的锁。而这些锁恰恰是用来维持对象一致性的。如果如此,写线程写入数据正写到一半,并强行终止,那么对象就会被写坏,同时,由于锁已经被释放,另一个等待该锁的读线程就读到了这个不一致的对象,悲剧发生。
- 线程中断 线程中断并不会使线程立即退出,而是给线程发送一个通知,告知目标线程,有人希望你退出!至于目标线程接到通知后如何处理,则完全由目标线程自行决定。
public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(){ public void run() { while(true){ if(Thread.currentThread().isInterrupted()){ System.out.println("Interruted!"); break; } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); //设置中断状态的目的:Thread.sleep()方法由于中断而抛出异常,此时,它会清除中断标记 //如果不加处理,那么在下一次循环开始时,就无法捕捉这个中断,故在异常处理中,再次设置中断 //标记位 Thread.currentThread().interrupt(); } Thread.yield(); } }; }; t1.start(); Thread.sleep(2000); t1.interrupt(); }
- 等待(wait)和通知(notify)当一个对象实例调用wait()方法后,当前线程就会在这个对象上等待。比如,线程A中,调用了obj.wait()方法,那么线程A就会停止继续执行,而转为等待状态。等待到何时结束呢?线程A会一直等到其他线程调用了obj.notify()方法为止。这时,obj对象就成为多个线程之间的有效通信手段。obj.wait()方法并不是可以随便调用的。他必须包含在对应的synchronzied语句中,无论是wait()或者notify()都需要首先获得目标对象的一个监视器。
public class Test07 { final static Object object = new Object(); public static class T1 extends Thread{ @Override public void run() { synchronized (object) { System.out.println(System.currentTimeMillis()+":T1 start! "); try{ System.out.println(System.currentTimeMillis()+":T1 wait for object"); object.wait(); }catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis()+"T1 end!"); } } } public static class T2 extends Thread{ @Override public void run() { synchronized (object) { System.out.println(System.currentTimeMillis()+":T2 start! notify one thread"); object.notify(); System.out.println(System.currentTimeMillis()+":T2 end!"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { Thread t1 = new T1(); Thread t2 = new T2(); t1.start(); t2.start(); }}
Object.wait()和Thead.sleep()方法都可以让线程等待若干时间。除了wait()可以被唤醒外,另一个主要区别是wait()方法会释放目标对象的锁,而Thread.sleep()方法不会释放任何资源。