——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
1、进程: 是一个正在执行中的程序。
每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元(线程)。
2、线程:就是进程中的一个独立的控制单元。
线程控制着进程的执行。
一个进程中,至少一个或以上的线程。
3、Java JVM 启动的时候会有一个进程 Java.exe
(1)、该进程中至少有一个(当然就是多个)线程负责 Java 程序的执行。
(2)、而且这个线程运行的代码存在于 main 方法中。
(3)、该线程称为主线程。
4、扩展:其实更细节说明 Jvm ,Jvm 启动不止一个线程,还有负责垃圾回收机制的线程
5,线程状态
(1)、新状态:线程对象已经创建,还没有在其上调用start()方法。
(2)、可运行状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态。当start()方法调用时,线程首先进入可运行状态。在线程运行之后或者从阻塞、等待或睡眠状态回来后,也返回到可运行状态。
(3)、运行状态:线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。
(4)、等待/阻塞/睡眠状态:这是线程有资格运行时它所处的状态。实际上这个三状态组合为一种,其共同点是:线程仍旧是活的,但是当前没有条件运行。换句话说,它是可运行的,但是如果某件事件出现,他可能返回到可运行状态。
(5)、死亡态:当线程的run()方法完成时或调用stop()就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
6 创建方式
创建线程的第一种方式:继承Thread类。
如下:
package com.itheima;
public class duoxiangcheng extends Thread {
public static void main(String[] args) {
// TODO Auto-generated method stub
duoxiangcheng duo =new duoxiangcheng();
duo.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {
System.err.println("A__________"+i);
}
}
创建线程的第二种方式:实现Runnable接口。
如下:
package com.itheima;
public class duoxiangcheng implements Runnable{
//实现步骤:
//
//1,定义类实现Runnable接口
//2,覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。
//3,通过Thread类建立线程对象。
//4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
//
//5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 50; i++) {
System.err.println(Thread.currentThread().getName()+"_____"+i);
}
}
public static void main(String[] args) {
duoxiangcheng d = new duoxiangcheng();
Thread t1 =new Thread(d);//实例化线程
t1.setName("d1");//设置线程名字
t1.start();//开启线程
Thread t2 =new Thread(d);
t2.setName("d22");
t2.start();
}
}
实现方式和继承方式有什么区别:
(1)、实现方式好处:避免了单继承的局限性
(2)、在定义线程时:建议使用实现方式
(3)、两种方式区别:
1.继承Thread:线程代码存放在 Thread 子类 run 方法中
2.实现Runnable:线程代码存放在接口的子类的 run 方法中
议使用第二种线程创建方法。因为第二种方式更加体现面向对象思想
附:也可以直接创建对象调用run方法,但就不是多线程运行了,