进程和线程的概念
进程((process)
就是正在执行的程序,从Windows角度讲,进程是含有内存和资源并安置线程的地方.
线程(thread)
进程可进一步细化为线程,是一个进程内部的最小执行单元(执行任务).
线程与进程之间的关系
- 一个进程可以包含多个线程,一个线程只能属于一个进程,线程不能脱离进程而独立运行;
- 每一个进程至少包含一个线程(称为主线程);在主线程中开始执行程序, java程序的入口main()方法就是在主线程中被执行的。
- 在主线程中可以创建并启动其它的线程; 一个进程内的所有线程共享该进程的内存资源
。
多线程的概念
多线程是指程序中包含多个执行单元,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
何时需要多线程
- 程序需要同时执行两个或多个任务。
- 程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
- 需要一些后台运行的程序时。
多线程的好处
- 提高程序的响应.
- 提高CPU的利用率.
- 改善程序结构,将复杂任务分为多个线程,独立运行
多线程的不利方面
- 线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
- 多线程需要协调和管理,所以需要CPU时间跟踪线程;
- 线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;
创建线程
继承Thread类的方式
public class Thread1 extends Thread {
/*
在Java中实现线程,可以通过继承Thread类,重写其中的run()方法
Thread类本身的run()方法不执行任何操作,如果我们重写了run()方法,当线程启动时,它将执行run()方法
*/
@Override
public void run() {
super.run();
for (int i = 0; i <100 ; i++) {
System.out.println("Thread:"+i);
}
}
}
//测试类
public class Test {
public static void main(String[] args) {
Thread1 thread1=new Thread1();
thread1.start();
}
}
实现Runnable接口的方式
/*
创建线程。也可以通过实现Runnable接口,重写其中的run()方法
Runnable接口的存在主要是为了解决Java中不允许多继承的问题。
*/
public class Thread2 implements Runnable {
@Override
public void run() {
for (int i = 0; i <100 ; i++) {
System.out.println("Thread2:"+i);
}
}
}
public class test2 {
public static void main(String[] args) {
Thread2 thread2=new Thread2();
Thread t1=new Thread(thread2);
t1.start();
}
}
继承方式和实现方式的联系与区别
区别:
继承Thread: 线程代码存放Thread子类run方法中。
实现Runnable:线程代码存在接口的子类的run方法。
实现Runnable的好处:
1)避免了单继承的局限性
2)多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。
线程状态
线程在它的生命周期中会处于不同的状态:
线程的状态:
- 新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态
- 就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件,只是没分配到CPU资源
- 运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run()方法定义了线程的操作和功能
- 阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执行,进入阻塞状态
- 死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束