看完J2SE的视频,不知道大家有没有像我这样的疑问:为什么该视频中只讲线程,涉及到的也是线程的并发问题。以前自考《操作系统概论》中讲的是进程间的互斥和并发。这之间有什么关系吗?
通过一通地查资料,我发现了其实还是一个全局观的问题。大家看我画的一张图就知道了。
其实学是学了,却没有想过,操作系统到底是什么,java又是什么。
1.现在为了讲明白最开始的疑问,先说明一下什么是线程,什么是进程,以及他们之间的区别:
简而言之,一个程序至少有一个进程,一个进程至少有一个线程. 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
使用java语言编写出的程序,在平台上运行。相对操作系统所拥有的众多进程而言就是其中一个。所以在J2SE的视频中讲的是线程和多线程的并发问题。
2.线程的两种启动方法
1.实现Runnable接口
public class TestThread1 {
public static void main(String[] args){
Runner1 r = new Runner1();
Thread t = new Thread(r);
t.start();
for(int i=0;i<100;i++){
System.out.println("Main Thread ------- " + i);
}
}
}
class Runner1 implements Runnable {
public void run(){
for(int i=0;i<100;i++){
System.out.println("Runner1:" + i);
}
}
}
2.继承Thread类
public class TestThread2 {
public static void main(String[] args){
Runner1 r = new Runner1();
r.start();
for(int i=0;i<100;i++){
System.out.println("Main Thread ------ " + i);
}
}
}
class Runner1 extends Thread {
public void run() {
for(int i=0;i<100;i++){
System.out.println("Runner1:" + i);
}
}
}
这两种方法实现接口更好,更具有灵活性。
3.线程的状态的转换
a、线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,当我们new了这个对象后,线程就进入了初始状态;
b、当该对象调用了start()方法,就进入就绪状态;
c、进入就绪状态后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态;
d、进入运行状态可复杂了。
d.1、run()方法或main()方法结束后,线程就进入终止状态;
d.2、当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源)。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片;
d.3、线程调用了yield()方法,意思是放弃当前获得的CPU时间片,回到就绪状态,这时与其他进程处于同等竞争状态,OS有可能会接着又让这个进程进入运行状态
4.总结:这部分的知识的重难点在于锁。这部分的理解还尚浅,随着软考的复习,可以结合pv操作进行对比总结。