并发线程的知识是很重要而且比较杂的知识点,所以需要花不少时间用于整理。本博客整理线程的一些比较重要而且比较基础的知识点,帮忙读者入门,注意只是学习并发编程的一些基础点,要系统学习的是需要多看看书籍还是花不少时间整理的。本博客是在参加培训后做的笔记,仅供学习参考
充分利用cpu资源,可以并发的处理任务
单核cpu也是适合多线程的,单核的cpu系统中,一个进程中是允许有多个线程的。而且单线程在等待io时,cpu就空闲出来了
线程是进程的一部分,可以理解为一条代码的执行流,完成一组代码的执行,这组代码往往被称之为一个任务
从执行代码角度,也可以说CPU就是执行代码的
对于stop线程,读者可能会想能不能用Thread.stop
?这种方法是绝对不允许的,在Oracle官网也对比进行了比较详细的说明,https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html
归纳起来就是这样的, 线程不安全 使用stop会释放所有持有的锁,会导致被保护的资源不一致,使得程序结构不确定
ok,然后如何正确的stop线程?
private volatile stop = false;
public void doWork() {
Thread t = new Thread(() -> {
while (!stop) {
// do someting
}
});
}
public void doStop() {
stop = true;
}
interrupt()
方法Thread.interrupt();
创建线程的方法从源码角度是只有一种的,也即new Thread
,不过实现方式语法上来说就有很多种,比如实现Runnable接口,或者是通过继承Thread类实现,或者是通过Callable来实现,或者是通过线程池来创建等等,这种方法只是语法上的不同,要从源码角度来说就只有一种,所以面试时候可以列举这些方法,然后和面试官说从源码角度上来只有一种,详情可以参考我上篇博客并非编程系列之创建线程的方法有多少种?
在idea里,用快捷键看一下Threa的状态,如图:
所以,线程的状态是有这几种的:
Thread t = new Thread(() -> {
System.out.println(Thread.currentThread().getName());
});
System.out.println("创建线程后状态:" + t.getState());
创建线程后状态::NEW
Thread t = new Thread(() -> {
System.out.println(Thread.currentThread().getName());
});
t.start();
System.out.println("Thread.start()之后的状态:" + t.getState());
Thread.start()之后的状态:RUNNABLE
Thread t1 = new Thread(() -> {
synchronized (ThreadStatusExample_Synchronized.class) {
System.out.println("t1抢到锁");
}
});
synchronized (ThreadStatusExample_Synchronized.class) {
t1.start();
Thread.sleep(1000L);
System.out.println("t1抢不到锁时的状态:"+t1.getState());
}
t1抢不到锁时的状态:BLOCKED t1抢到锁
public static void main(String[] args) throws Throwable {
Thread t1 = new Thread(() -> {
LockSupport.park();
});
t1.start();
Thread.sleep(2000L);
System.out.println("t1 被park后的状态:" + t1.getState());
LockSupport.unpark(t1);
}
t1 被park后的状态:WAITING
private static volatile boolean running = true;
public static void main(String[] args) throws Throwable{
Thread t = new Thread(() -> {
while (running) {}
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.start();
// volatile boolean标志的变量设置为false,让子线程退出循环
running = false;
Thread.sleep(1000L);
System.out.println("Threa.sleep之后的状态:" + t.getState());
}
Threa.sleep之后的状态:TERMINATED
这种情况,可以用Thread.sleep,等到线程执行完成就会打印出来
Thread才是线程对象,Runable和Callable可以理解为线程任务,需要开发者自己去实现接口