1.线程的基本概念
什么是线程,线程就是程序中单独顺序的流控制,线程本身不能运行,它只能用于程序中,只能使用分配给程序的资源和环境。
通常一个进程可以包含若干个线程,它们可以利用进程所拥有的资源。在引入线程的OS中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。由于线程比进程小,基本上不拥有系统资源,所以它的调度所付出的开销会小的多,能更高效地提高系统内多个程序之间并发执行的程度。
2.进程与线程的比较
线程又称轻型进程或者进程元,相应的传统进程又称重型进程,传统进程相当于只有一个线程任务,在有了线程之后,一个进程有一个或者多个线程任务。
1)进程是资源分配的基本单位,而线程是任务调度和运行的基本单位,在任务调度方面或者线程调度方面不需要设计存储管理方面的操作所以开销更小。
2)多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内空间和一组系统资源,有可能相互影响。
3)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程的切换的负担要小。
3.线程的生命周期
1)新建线程(NEW):通过New关键字创建了Thread类或者子类的对象
2)就绪状态(RUNNABLE):是创建的线程对象调用了start方法,,这时的线程等待时间片轮转到自己这,以便获得CPU;第二种情况是线程在处于RUNNABLE状态时并没有运行完自己的run方法,时间片用完之后回到RUNNABLE状态,还有种情况就是处于BLOCKED状态的线程结束了当前的BLOCKED状态之后重新回到RUNNABLE状态。
3)执行状态(RUNNING):这时的线程指的是获得CPU的RUNNABLE线程,RUNNABLE状态是所有线程都希望获得的状态。
4)DEAD:处于RUNNING状态的线程,在执行完run方法后,就变成了DEAD状态了。
5)BLOCKED:这种状态指的是处于RUNNING状态的线程,处于某种原因,比如调用了sleep方法或者进行IO操作让出当前CPU给其他线程。
4.单线程的应用
当程序启动运行时,就自动产生一个线程,主方法main就是在这个主线程上运行。
如图下图所示
可以看到main方法是运行在主线程上面的。我们的程序都是由线程来执行的
5.多线程概念
A.多线程的概念:
1)一个进程可以包含一个或者多个线程
2)一个程序实现多个代码同时交替运行,就需要产生多个线程。(比如同一个方法运行在多个线程上,第一个线程可能运行到第3行,而此时第二个线程可能只运行到第1行,第三个线程可能已经运行完了)
3)CPU随机的抽出时间,让我们的程序一会做这件事情,一会做另外一件事情。
B.多线程的目的
其实就是最大限度的利用CPU资源,当某一线程的处理不需要占用CPU而只和I/O等资源打交道时,让需要占用CPU资源的其它线程有机会获得CPU资源。
6.多线程在Java中基本应用
同其他编程语言相比,Java内置了多线程的实现方法。表现在程序上有两种实现方式:
1)继承Thread类,重写run方法
2)实现Runnable接口,实现run方法
在实践多线程编程之前我们来熟悉以下Thread类和Runnable接口。
Thread类:继承了object超类以及实现了Runnable接口。
API里面的介绍:
A thread is a thread of execution in a program.The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
Every thread has a priority.Threads with higher priority are executed in prefernce to threads with lower priority.Each thread may or may not also be a daemon .When code running in some thread creates a new Thread Object,the new thread has its priority initially set equals to the priority of the creating thread,and is a daemon thread if and only if the creating thread is a daemon.
主要意思也就是线程是一个运行程序中的控制流。Java虚拟机允许多个线程同时运行。每个线程都有一个优先级,虚拟机会偏向选择优先级高的进程运行,线程可以是一个守护进程也可以不是一个守护线程,如果一个线程是守护线程,那么创建它的线程肯定也是守护线程。
Runnalbe和Thread雷同。因为Thread实现了Runnalbe接口。
7.多线程的实践
Thread类
public class TestThread {
public static void main(String[] args) {
Thread1 thread1=new Thread1();
thread1.start();
}
}
class Thread1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread " + i);
}
}
}
在System.out.println(“Thread”+i)打印出设置断点,运行程序如下:
可以看到现在程序有两个线程,打断点的线程处于挂起状态(Suspend,这个后面会讲到).
执行结果:
实现Runnable接口
class Thread2 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread2 " + i);
}
}
}
public static void main(String[] args) {
Thread1 thread1=new Thread1();
Thread thread2=new Thread(new Thread2());
thread1.start();
thread2.start();
}
在thread2中打断点运行,如下
可以看到三个线程
对于单核CPU来说,某一时刻只能有一个线程在执行(微观串行),从宏观角度来说,多个线程在同时执行(宏观并行)。
对于双核或双核以上的CPU来说,可以真正做到微观并行。