线程的生命周期包括五个阶段
1 新建状态:创建了一个新的线程对象
2 就绪状态:线程对象创建后,其他线程调用了该对象的start()方法,该状态的线程位于可运行线程池中,变得可运行,等待CPU的使用权
3 运行状态:就绪状态的线程获取了CPU的使用权,执行程序代码
4 阻塞状态:线程因为某种原因放弃了CPU的使用权,暂时停止运行,直到线程进入就绪状态,才有机会转到运行状态
阻塞的状态分为三种情况:
1.等待阻塞:运行的线程执行wait()方法,jvm会把该线程放入等待池里,wait会释放持有的锁
2.同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,jvm会把该线程放入锁池中
3.其他阻塞:运行的线程执行sleep方法或者join方法时或者发出了I/O请求,JVM会把该线程设置为阻塞状态
5 死亡状态:线程执行完或因为异常退出了run方法,该线程结束生命周期
线程的调度 1 线程的优先级Java线程优先级用整数表示 1-10 数字越大优先级越高
Thread类提供了三个静态常量表示线程的优先级
static int MAX_PRIORITY ------10
static int MIN_PRIORITY ------1
static int NORM_PRIORITY -------5
线程的优先级不是固定不变的,可以通过setPriority(int newPriority)方法对它进行设置
thread.setPriority(Thread.MAX_PRIORITY);
thread.setPriority(5);
2 线程休眠如果想人为控制线程的执行顺序,可以让正在执行的线程暂停,用sleep方法
代码演示
package com.jian;
public class Thread01 extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "正在输出i: "+ i);
if (i == 2) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
-------------------------
package com.jian;
public class Thread02 extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "正在输出i: "+ i);
}
}
}
-------------------------
package com.jian;
public class Test {
public static void main(String[] args) {
Thread01 thread01 = new Thread01();
Thread02 thread02 = new Thread02();
thread01.start();
thread02.start();
}
}
输出
Thread-0正在输出i: 0 Thread-1正在输出i: 0 Thread-0正在输出i: 1 Thread-1正在输出i: 1 Thread-1正在输出i: 2 Thread-1正在输出i: 3 Thread-1正在输出i: 4 Thread-0正在输出i: 2 Thread-1正在输出i: 5 Thread-1正在输出i: 6 Thread-1正在输出i: 7 Thread-1正在输出i: 8 Thread-1正在输出i: 9 Thread-0正在输出i: 3 Thread-0正在输出i: 4 Thread-0正在输出i: 5 Thread-0正在输出i: 6 Thread-0正在输出i: 7 Thread-0正在输出i: 8 Thread-0正在输出i: 9
可以看到 Thread-0因为休眠了5秒,使用Thread-0 剩下的都在最后执行
3 线程让步Thread.yield()方法,暂停当前正在执行的线程对象,把执行机会让给相同或者优先级更高的线程
因为Java虚拟机默认是抢占式调度模型,所有线程都会抢占CPU资源,所以在执行线程让步时,并不能保证立即执行其他线程
4 线程加入join()方法 在某个线程中调用其他线程的join方法,则当前线程进入阻塞状态,直到另外一个线程执行完毕,这个线程才会继续执行
package com.jian;
public class Thread03 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 6; i++) {
System.out.println(Thread.currentThread().getName() + "输入: "+i);
}
}
}
class Example{
public static void main(String[] args) {
Thread t = new Thread(new Thread03(),"thread1");
t.start();
for (int i = 0; i < 6;i++) {
System.out.println(Thread.currentThread().getName() + "输入: "+i);
if (i == 2) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
输出
main输入: 0 thread1输入: 0 main输入: 1 thread1输入: 1 thread1输入: 2 thread1输入: 3 thread1输入: 4 thread1输入: 5 main输入: 2 main输入: 3 main输入: 4 main输入: 5
可以看到,调用了t的join方法,所以main线程等待t线程执行完才开始执行
5 多线程同步同步代码块:
synchronized关键字
package com.Sale;
public class SaleThread implements Runnable{
private int ticket = 10;
Object lock = new Object();
@Override
public void run() {
while (true) {
synchronized (lock) {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在发售第: " + ticket-- + "张票");
}
}
}
}
}
class Example1{
public static void main(String[] args) {
SaleThread saleThread = new SaleThread();
new Thread(saleThread,"售票窗口1").start();
new Thread(saleThread,"售票窗口2").start();
new Thread(saleThread,"售票窗口3").start();
new Thread(saleThread,"售票窗口4").start();
}
}
同步方法:
package com.Sale;
public class SaleThread01 implements Runnable{
private int ticket = 10;
Object lock = new Object();
private synchronized void saleTicket(){
if (ticket > 0 ) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在发售 "+ ticket--+"张票");
}
}
@Override
public void run() {
while (true) {
saleTicket();
}
}
}
class Example11{
public static void main(String[] args) {
SaleThread saleThread = new SaleThread();
new Thread(saleThread,"售票窗口1").start();
new Thread(saleThread,"售票窗口2").start();
new Thread(saleThread,"售票窗口3").start();
new Thread(saleThread,"售票窗口4").start();
}
}
6 同步锁



