进程:正在执行的程序,其实是应用程序在内存中的进行的那片空间。进程不执行代码。
线程:进程中的一个执行单元,负责对进行中的程序运行的,一个进程中至少一个线程。
多线程的特点:可以实现多部分的功能。这叫并发。
多线程的使用可以合理的利用cpu的资源,如果线程过多,反而会降低性能。
哪个线程出异常,只跟出问题的线程有关,跟其它的线程毫无关系。
实现线程的两种方法
- 1
java中提供了Thread类,从这个类中实例化的对象代表线程
创建线程
1.定义一个类继承线程类。
2.重写run方法。
3.创建子类对象,就是创建线程对象。
4.调用start方法,开启线程并执行,同时会告诉jvm调用run方法。
class ThreadTest extend Thread {
private int c = 10;
public void run( ){ // run方法中的代码,可以称为线程任务。
while(true){
c--;
System.out.println(c+"");
if(c== 0){
return;
}
}
}
}
注意 :
1.如果不调用strat方法,那么线程永远不会启动。
2.如果start方法调用一个已经启动的线程,就会抛出IlegealThreadStartException异常。
调用run方法和调用start方法有什么区别?
1.调用run方法,只是对象调用,不会启动线程。
2.调用start方法,启动线程,并jvm调用run方法。
- 2
Runnable接口
当一个类已经有了父类,但是只要这个代码进行多线程,java不支持多继承,所以不能再继承Thread类,
如果父类继承Thread类,那么全部类都是线程类,没必要这样。java就提供了Runnable接口,实现接口使其
具有使用线程的功能
创建线程
1.定义一个类实现Runnable接口。 (避免了单继承的局限性)
2.重写run方法。将线程任务定义到run方法中。
3.创建Thread类的对象, (创建Thread类对象才可以创建线程)
4.将Runnable实现类作为参数传递给Thread类的构造方法。
(因为线程任务封装到了Runnable接口中的实现类中,那么就需要将这个实现类对象作为参数传入Thread的构造方法中,
线程对象创建时就可以明确要执行的线程任务。)
5.调用statr方法,启动线程,并jvm调用run方法。
class ThreadTest implements Runnable {
pubilc void run(){
}
}
public static void mian(String[] args){
new ThreadTest().stat();
}
多线程在执行时,在栈内存中,每个线程都有属于自己的栈内存空间。进行方法的进栈和出栈,
当执行线程任务结束了,线程会自动在栈内存中释放,当所有执行线程都结束,那么此时线程就结束了。