线程的一些记录
线程的定义
线程是程序执行的最小单位,每当程序运行时,会创建一个进程,然后进程中每当出现一个任务就会生成或者调度一个线程进行处理。
一个进程包含多个线程,所有线程共享进程的资源,但是每个线程都有自己的堆栈和变量。
单线程:银行只有一个员工,处理完A的请求再去处理B的请求,必须一个一个处理。
多线程:银行有多个员工,A和B的请求在同时处理或者一个员工处理A的请求,过了一会,B来了,另外一个员工去处理了,大家互不影响,但是效率提升了。
线程的实现
- 继承Thread,Thread类本身实现了Runable类
public class Demo {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("当前代码段正在被调用的线程名称:" + Thread.currentThread().getName());
System.out.println("当前线程的名字:" + this.getName());
}
}
- 实现 Runable
同样是重写run方法,但是最后调用时通过创建Thread来进行启动线程。
因为类只能继承一次,所以很多时候可以用Runable来实现线程,相对比较灵活。
public class Demo {
public static void main(String[] args) {
MyThread2 thread = new MyThread2();
new Thread(thread).start();
}
}
class MyThread2 implements Runnable {
@Override
public void run() {
System.out.println("当前代码段正在被调用的线程名称:" + Thread.currentThread().getName());
}
}
- 实现 Callable
FutureTask类也可以放入new Thread中进行启动,因为它实现了RunnableFuture类,RunnableFuture类又继承了Runnable类,所以它可以认为是一个Runnable类。
class MyThread3 implements Callable {
public class Demo {
public static void main(String[] args) throws Exception {
MyThread3 thread = new MyThread3();
FutureTask<Object> futureTask = new FutureTask<>(thread);
new Thread(futureTask).start();
// 是否执行完成
System.out.println(futureTask.isDone());
// 手动关闭线程,下面的get会报错
// 如果传入false,不会关闭,因为false只会关闭还未开始的任务。(可能是用来停止订单任务的?这个我试了几次,还是有点迷糊)
//沉睡
// Thread.sleep(10);
// futureTask.cancel(true)
// 这里会发生阻塞,会一直等到任务执行完毕才返回
Object o = futureTask.get();
System.out.println(o.toString());
}
}
@Override
public Object call() throws Exception {
System.out.println("当前代码段正在被调用的线程名称:" + Thread.currentThread().getName());
//Thread.sleep(5000);
return "执行完毕,线程名称为"+Thread.currentThread().getName();
}
}
一般情况下用的比较多的还是实现Runnable,但是如果有需要返回值的线程,还是得用到Callable,直接继承Thread一般使用较少,因为不灵活。
线程的生命周期
- 创建new
创建也就是执行了上面的new Thread()。
- 就绪runnable
就绪是调用了start方法,在等待cpu分配资源。
- 运行中running
抢占到资源后就调用run方法,成为运行中状态。
- 阻塞blocked
在运行过程中,因为sleep(不会释放锁),wait等进入等待状态,然后它的资源会被其他线程抢占使用,必须等待notify或者notifyAll()方法唤醒才能重新开始,再次抢占资源。
- 销毁terminated
线程执行完成或者发生异常或者被中断,线程都会结束,然后会被销毁释放。
sleep和wait的区别
sleep在Thread类中,wait在Object类中。
sleep不会释放锁,wait会释放锁。
sleep使用interrupt()来唤醒,wait需要notify或者notifyAll来通知。
之后想到再写