线程基础
Thead类
- 1.定义Thread类的子类,重写run()方法,该run()方法代表了线程需要完成的任务
- 2.创建Thread子类实例,即创建线程对象
- 3.调用线程对象的start()方法启动线程
package com.hexy.thread.demo;
public class ThreadDemo1 extends Thread{
@Override
public void run(){
System.out.println("hello concurrent world");
}
public static void main(String[] args) {
System.out.println("create thread");
ThreadDemo1 demo1 = new ThreadDemo1();
System.out.println("start thread");
demo1.start();
}
}
Runnable接口
- 1.定义Runnable接口的实现类,并重写接口的run方法
- 2.创建Runnable实现类实例,并以此实例作为Thread类的target来创建Thread对象,该Thread对象才是真正的线程对象
package com.hexy.thread.demo;
public class ThreadDemo2 implements Runnable {
@Override
public void run() {
System.out.println("hello concurrent world");
}
public static void main(String[] args) {
System.out.println("implements runnable interface");
ThreadDemo2 demo2 = new ThreadDemo2();
System.out.println("creat thread");
Thread thread = new Thread(demo2);
System.out.println("start thread");
thread.start();
}
}
Callable接口
- 1.创建Callable接口的实现类,实现call方法,该call方法将作为线程的执行体,且该call方法有返回值,再创建Callable实现类的实例
- 2.使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call方法的返回值
- 3.使用FutureTask对象作为Thread对象的target创建并启动新线程
- 4.使用FutureTask对象的get方法来获得子线程执行结束后的返回值
package com.hexy.thread.demo;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadDemo3 implements Callable {
@Override
public Object call() throws Exception {
int sum = 0;
for(int i=0;i<100;i++){
sum+=i;
}
return sum;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask task = new FutureTask(new ThreadDemo3());
Thread thread = new Thread(task);
thread.start();
System.out.println(task.get());
}
}
线程的生命周期
- 1.新建:new关键字创建线程对象时的状态
- 2.就绪:通过线程对象的start()方法启动线程时对应的状态,此时线程并不一定马上进入运行状态,线程的运行由操作系统的调度程序控制
- 3.运行:线程获得cpu的执行权,线程正在执行需要执行的代码
- 4.阻塞:BLOCKED称为阻塞状态,或者说线程已经被挂起,它睡着了,原因通常是它在等待一个锁
- 5.等待:分为有限期等待和无限期等待
- 6.结束:线程结束。若干种场景
线程阻塞
- 1.线程在等待一个锁,当尝试进入一个synchronizied语句块/方法时,锁已经被其他线程占有,就会被阻塞,知道另一个线程走完临界区或者发生了相应锁对象的wait()操作后,它才有机会去争夺进入临界区的权利
- 2.处于阻塞状态的线程,即使对其调用thread.interrupt()也无法改变其阻塞状态,因为interrupt()方法只是设置线程的中断状态,不能唤醒处于阻塞状态的线程
- 3.ReentrantLock.lock()操作后进入的是WAITING状态,其内部调用的是LockSuport.park()方法
线程无限期等待
- 1.处于这种状态的线程不会被分配CPU执行时间,它们要等待被其它线程唤醒
- 2.没有设置timeout参数的Object.wait()
- 3.没有设置timeout参数的Thread.join()
- 4.LockSupport.park()
线程有限期等待
- 1.处于这种状态的线程也不会被分配CPU执行时间,不过无需等待其他线程显示的唤醒,在一定时间后它们会由系统自动唤醒
- 2.Thread.sleep()
- 3.设置了timeout参数的Object.wait()
- 4.设置了timeout参数的Thread.join()
- 5.LockSupport.parkNanos()方法
- 6.LockSupport.parkUntil()方法
线程结束
- 1.run()和call()执行结束,线程正常结束
- 2.线程抛出一个未捕获的Exception或Rrror
- 3.直接调用线程的stop()方法来结束线程
线程关系图:待续