这一部分内容来学习java的一些高级特性,包括:多线程,泛型,I/O操作,集合,枚举,反射,Annotation,Java数据库编程,Java网络编程,还有JDK5的一些新特性的学习。
在工作中这些知识是基本功,必须要打扎实!首先来学习多线程!
目标:
1.了解进程与线程;2.掌握java多线程的俩种实现方式;3.多线程的操作方法;4.线程的其他一些概念:状态变化、生命周期、同步与死锁等。
开始:
1.并发机制是由于CPU具备分时机制,每个进程都能循环获得自己的CPU时间片。
所谓多线程是指一个进程在执行过程中可以产生多个线程,这些线程可以同时存在,同时运行。
例如在使用Word时,我们每打开一个Word,对于操作系统而言就启动了一个进程,在这个进程之上又运行着许多的程序,例如拼写检查,那么这些程序就是一个个线程。如果word关闭,则拼写检查这些线程也就消失。但是一个线程关闭,不一定会导致进程关闭。
传统语言中一次只能运行一个程序块。而多线程机制可以同时运行多个程序块,使程序运行效率变高,也为程序设计提供了新的思维。例如:有些包含循环的线程可能需要一段时间来计算,这段时间便可以让另外一个线程做其他的处理。
2.java多线程有俩种实现方式:继承Thread类;实现Runnable接口
(1)继承Thread类
运行结果:
我们发现线程A和线程B是顺序执行的,实际上我们的线程并没有启动,仍然按照普通程序的顺序执行。要正确启动线程,应该调用从Thread类继承下来的start()方法。
执行结果:
俩个线程交错运行,哪个线程抢到了CPU资源,哪个线程就执行
在线程启动时,虽然调用的是start()方法,但是执行的却是run()方法的主体
这是因为线程的运行需要本机操作系统的支持。
我们看一下Thread类中是如何定义start()方法的
public synchronized void start() {
if(threadStatus!=0) throw new IllegalThreadStateException();
...start0();
...
}
public native void start0(){...}
实际上此处真正调用的是start0()方法,native关键字表示调用本机操作系统函数,因为多线程的实现是要靠本机操作系统支持。
还有,如果重复调用start()方法,会抛出异常。
(2)实现Runnable接口
接下来我们详细了解一下俩种方式的联系与区别
Thread类的定义:
public class Thread extends object implements Runnable {...}
实际上Thread类中的run()方法调用的是Runnable接口中的run()方法。
Thread类中定义的run()方法
public void run() {
if(target!=null){
target.run();//target是Runnable实例对象
}
}
所以如果要通过继承Thread类实现多线程,必须要重写run()方法
实现Runnable接口相对于继承Thread类实现多线程有显著的优势:
(1)适合多个相同程序代码的线程去处理同一资源
(2)可以避免由于java的单继承机制带来的局限,比如Thread子类只能调用一次start方法。
(3)增强程序的健壮性,代码可以被多个线程共享,代码与数据独立。
执行结果:三个线程各自卖了五张票,根本没有信息共享
执行结果: