线程操作相关API:
基础知识
什么是进程
进程
所谓进程,就是一块包含了某些资源的内存区域,操作系统利用进程把他的工作划分为一些功能单元。进程中包含一个或多个线程,用于自己私有的虚拟地址空间。该空间仅能被他所包含的线程访问。当操作系统创建一个主线程后,该进程会自动申请一个名为主线程或首要线程的线程。
简单来说,进程就是指正在运行的程序。也就是说,当一个程序进入内存运行,就变成了一个进程。
什么是线程
线程
线程是一个进程中的执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个程序也可以称为多线程程序。线程在切换时负荷小,所以线程也被称为轻负荷进程。
简而言之:一个程序运行后,至少有一个进程,一个进程中包含多个线程。
什么是多线程
多线程
多线程就是一个程序中有多个线程在同时执行。
线程和进程的区别
区别
一个进程至少有一个线程,线程的划分尺度小于进程。
进程应有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中,每个独立的线程有一个程序运行的入口,顺序执行序列,程序运行的出口,但是线程不能独立运行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
线程使用的场合
线程通常用于在一个程序中需要同时完成多个任务的情况,我们可以将每个任务定义为一个线程,使得他们一同工作。
并发原理
多个线程或进程“同时”运行只是我们感官上的一种表现,事实上进程和线程是并发运行的。OS的线程调度机制将时间划分为很多时间片段(时间片),尽可能的均匀分配给正在运行的程序。获取到时间片的线程或进程才会被执行,其他的则处于等待状态,而CPU则在这些进程和线程上来回切换运行。
微观上多个进程和线程是“走走停停”,宏观上是都在运行。这种都运行的现象叫并发。但不是绝对意义上的“同时发生”。
线程调度机制是OS提供的一个用于并发处理的程序,Java虚拟机自身也提供了线程调度机制,用于减轻OS切换线程带来的负担。
线程的五种状态
New:当我们创建一个线程时,该线程并没有纳入线程调度,其处于一个New状态。
Runnable:当调用线程的start方法后,该线程纳入线程调度控制,其处于一个可运行状态,等待分配时间片段以并发运行。
Running:当该线程被分配到了时间片段后,其被CPU执行,此时线程处于正在执行状态
Bolcked:当线程运行过程中可能出现阻塞状态,比如等待用于输入信息等,但阻塞状态不是百分之百出现的,具体要看代码中是否由相关要求。
Dead:当线程的任务全部执行完毕时,或在运行过程中派出一个未捕获的异常,那么线程结束,等待GC回收。
创建线程的方法
方法一——继承Thread类。
java.lang.Thread类是线程类,其每一个实例表示一个可以并发运行的线程,可以通过继承该类
并重写run方法来定义一个具体的线程。其中重写run方法的目的是定义该线程要执行的逻辑,启动线程
后调用线程的start方法而不是run方法,start方法会将当前线程纳入线程调度,使当前线程可以开始
并发运行。
创建线程的步骤:
1 定义一个类继承Thread。
2 重写run方法。
3 创建子类对象,就是创建线程。
调用start方法,开启线程并让线程执行,同时还会告诉JVM去调用run方法。
public class Demo_1 {
public static void main(String[] args){
MyThread myThread=new MyThread();//创建线程myhread的线程对象
myThread.start(); //开启线程
for (int i = 0; i < 10; i++) {
System.out.println("main线程!"+i);
}
}
}
class MyThread extends Thread{
public void run(){
for (int i = 0; i < 10; i++) {
System.out.println("run:正在执行!"+i);
}
}
}
执行结果:
方法一——实现Runnable接口。
实现Runnable接口并重写run方法来定义线程体,然后在创建线程时将Runnable的实例传入并启
动线程。
这样做的好处在于可以将线程与线程要执行的任务分离开来,减少耦合度。同时java是单继承的
定义一个类实现Runnable接口的这种做法可以更好的去实现其他父类或接口。
创建线程的步骤:
1、定义类实现Runnable接口。
2、覆盖接口中的run方法。。
3、创建Thread类的对象
4、将Runnable接口的子类对象作为参数传递给Thread类的构造函数。
5、调用Thread类的start方法开启线程。
public class Demo_1 {
public static void main(String[] args){
MyRunnable mn=new MyRunnable(); //创建线程myhread的线程对象
Thread thread=new Thread(mn);//创建线程对象
thread.start(); //开启线程,执行线程中的run()方法
for (int i = 0; i < 10; i++) {
System.out.println("main线程!"+i);
}
}
}
class MyRunnable implements Runnable{
@Override
public void run(){
for (int i = 0; i < 10; i++) {
System.out.println("run:正在执行!"+i);
}
}
}
运行结果:
Thread类、Runnable接口的区别及优缺点
继承Thread类:由于子类重写了Thread类的run方法,当调用start方法时,直接找子类的run。
优点:是可以直接使用Thread中的方法,代码简单。
缺点:是如果已经有了父类那么就不能再使用。
实现Runnable接口: Runnable 接口的类。该类然后实现 run 方法。然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程。
优点:好处是即使有了父类也没关系,因为接口可以多实现。
缺点:弊端是不能直接使用Thread中的方法,需要先获取到线程对象,才能得到Thread中的方法,
代码复杂