Java线程(一)线程概述、线程生命周期与线程控制方法
线程:每个运行的程序都是一个进程,在一个进程中还可以有一个或者多个执行流同时运行,这些执行流可以看做程序执行的一条条线索,被称为线程。
进程与线程的区别:
进程是系统中最小的执行单元。
线程是进程中的最小执行单元。
一个进程必须有至少一个线程。
进程中执行的功能是通过线程来实现的。
一个进程的所有线程共享进程中的所有资源(PC寄存器,上下文,本地栈)。
单进程多线程环境在微观上仍是一个线程一个线程去执行,只是多个线程在不停的切换执行。具体某一时间点执行哪个线程由系统调度器来决定,JVM负责创建与执行线程。
创建线程的两种方式:
1.继承继承Thread对象
2.实现Runnable接口
启动线程:
线程的生命周期:
线程控制:
线程控制有五个方法,分别是join,sleep,daemon,yield,priority方法。
join方法:
t.join()方法只会使主线程进入等待池并等待t线程执行完毕后才会被唤醒。并不影响同一时刻处在运行状态的其他线程。
下图中t1线程执行了join方法后主线程必须等待t1线程执行完才能执行。
sleep方法:
执行了sleep()使当前线程进入阻塞状态(当前线程),让出CUP的使用,在规定的时间内不参与CPU的竞争。
daemon方法:
首先Java的线程分为两类,用户线程与daemon线程(守护线程)
用户线程:顾名思义就是用户自己为了完成某些功能而创建的线程,main线程也算。
daemon守护线程:daemon线程是为用户线程提供服务的线程。比如说jvm的GC,当所有的用户线程结束的时候,守护线程会自动退出。
守护线程的特点:
1.创建守护线程时应该先调用setDaemon方法进行设置,在执行线程的start()方法,否则会报错。
2.守护线程只能用来服务用户线程,所以守护线程不能进行业务操作。
3.daemon线程创建的子线程仍然是daemon线程。
模拟一个守护线程的运行:
守护线程t1等待主线程结束才结束
yield方法:
yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。
priority方法:
java线程调度是基于优先级的抢占式调度,所以java线程可以设置优先级。优先级大的线程比优先级小的线程有更高的几率执行,并不是优先级高的线程一定先于优先级低的线程执行。
java线程的优先级取值范围1(Thread.MIN_PRIORITY)~10(Thread.MAX_PRIORITY),优先级越高抢占cpu资源的概率越高,子线程默认继承父线程优先级且无法超过父线程优先级。