2013-12-23 10:00:12
1. 当一个程序进入内存中运行时即变成一个进程,系统对运行中的程序都是以进程为单位管理的;
2. 进程三特征:
1 独立性: 资源独立,拥有私有的地址空间,不允许其他进程访问; 2 动态性:程序是静态的指令集合,而进程是运行的、动态的指令集合; 3 并发性:多个进程可以在一个处理器上并发执行;
3. 目前大多数操作系统采用效率更高的抢占式多任务操作策略。
4. 线程是进程的组成部分,一个进程可以拥有多个线程,线程可以拥有自己的堆栈、程序计数器和局部变量,但与所有属于该进程的其他线程共享该进程拥有的系统资源。
5. 多线程编程优点:
1 进程之间不能共享内存,线程可以; 2 系统创建线程的代价小于创建进程的代价,因此效率更高; 3 Java语言内置多线程编程,简洁方便。
6. 线程的创建和启动:
1 继承Thread, currentThread方法返回正在执行的线程的线程对象; 2 继承Thread的线程之间不能共享线程类的实例变量; 3 实现Runnable, Runnable实例作为Thread的target用来创建Thread,但是Thread才是真正的线程对象; 4 实现Runnable的多个线程可以共享线程类(Runnable实现类)的实例变量;
7. 从Java 5开始可使用Callable和Future创建线程。
8. 线程的生命周期:
1 周期:新建-->就绪-->运行-->阻塞-->死亡; 2 线程对象调用了start()方法启动之后,线程处于就绪状态,至于何时运行,取决于JVM的线程调度策略,同时如果直接调用线程对象的run方法,那么线程并未启动,只不过是在主线程中执行了run方法而已; 3 Running状态,当线程获取CPU时就进入了Running状态,要么执行完成,要么被其他线程抢占CPU,这是抢占式策略的基础;
9. 发生如下情况时当前线程进入阻塞状态:
1 当前线程调用sleep()方法主动放弃CPU资源; 2 调用了一个阻塞式的IO方法,直到该方法返回之前处于阻塞状态; 3 线程试图获取一个同步监视器,但该同步监视器被其他线程持有; 4 线程在等待被唤醒(notify); 5 程序调用线程的suspend()方法主动挂起,该方法容易造成死锁,不推荐使用;
10. 发生如下情况将解除线程阻塞,进入就绪状态:
1 sleep()方法过了指定时间; 2 阻塞的IO方法已经返回; 3 获得等待的同步监视器; 4 被其他线程唤醒; 5 处于挂起状态的线程调用resume()回复;
11. 线程只能从阻塞状态进入就绪状态,不能直接进入运行态,运行状态和就绪状态之间的切换不受程序控制,由系统调度策略控制。
12. 有一种情况比较特殊:就是调用yield()方法可以直接从运行态转到就绪状态。
13. 线程死亡,线程在如下几种情况下死亡:
1 run()或者call()方法执行结束; 2 线程抛出一个未捕获的Exception或者Error; 3 直接调用该线程的stop方法,但是该方法容易造成死锁,不推荐使用;
14. 对新建状态的线程不能两次调用start方法,否则会抛出异常。
15. 简单的线程控制:
1 join线程:在一个线程中调用其他线程的join方法后,主调线程将进入阻塞状态,知道被join的线程执行完成为止; 2 后台线程:也叫Daemon Thread,指的是在后台运行的,为其他线程提供服务的线程。 3 后台线程有个特点,如果所有的前台线程全部死亡,则后台线程自动死亡。 4 Thread t = new Thread(); 5 t.setDaemon(true);即可将一个线程设置为后台线程,但是该方法只能在start方法之前调用。 6 前台线程创建的默认是前台线程,后台线程创建的默认是后台线程。
16. 线程睡眠,Thread.sleep()方法可以让当前线程睡眠,在此期间,即便是没有其他线程,该线程亦不会运行,直到睡眠时间到。
17. 线程让步,Thread.yield()方法可以让当前执行的线程暂停,并不阻塞,然后重新进入就绪状态。其实质只是让当前线程暂停一下。
18. sleep和yield方法的异同:
1 sleep方法执行后会给其他线程执行机会,但是yield方法执行后,只会给优先级较高的线程执行机会; 2 sleep时候线程进入阻塞状态,yield后线程又进入就绪状态。 3 sleep抛出异常,而yield方法没有; 4 sleep有更好的移植性。