并发编程系列之线程基础知识回顾(代码片段)

smileNicky smileNicky     2022-12-25     127

关键词:

并发线程的知识是很重要而且比较杂的知识点,所以需要花不少时间用于整理。本博客整理线程的一些比较重要而且比较基础的知识点,帮忙读者入门,注意只是学习并发编程的一些基础点,要系统学习的是需要多看看书籍还是花不少时间整理的。本博客是在参加培训后做的笔记,仅供学习参考

问题1、使用多线程的目的是什么?

充分利用cpu资源,可以并发的处理任务

问题2、单核cpu不适合多线程?

单核cpu也是适合多线程的,单核的cpu系统中,一个进程中是允许有多个线程的。而且单线程在等待io时,cpu就空闲出来了

问题3、线程什么时候让出cpu?

  • 线程阻塞时,使用wait、await等待io时候
  • 线程sleep时,使用了sleep
  • 线程yield时候,使用了yield
  • 线程结束的情况

问题4、什么是线程?

线程是进程的一部分,可以理解为一条代码的执行流,完成一组代码的执行,这组代码往往被称之为一个任务

问题5、CPU是做什么工作的?

从执行代码角度,也可以说CPU就是执行代码的

问题6、如何正确stop线程

对于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线程?

  • 1、使用volatile boolean变量来标记线程是否stop
private volatile stop = false;
public void doWork() 
     Thread t = new Thread(() -> 
         while (!stop) 
             // do someting
         
     );
 

public void doStop() 
    stop = true;

  • 2、使用线程的interrupt()方法
Thread.interrupt();
  • 3、对于blocking io的处理,使用interruptibleChannel来替代blocking io

问题7、创建线程的方法有多少种?

创建线程的方法从源码角度是只有一种的,也即new Thread,不过实现方式语法上来说就有很多种,比如实现Runnable接口,或者是通过继承Thread类实现,或者是通过Callable来实现,或者是通过线程池来创建等等,这种方法只是语法上的不同,要从源码角度来说就只有一种,所以面试时候可以列举这些方法,然后和面试官说从源码角度上来只有一种,详情可以参考我上篇博客并非编程系列之创建线程的方法有多少种?

问题8、线程有哪几个状态?

在idea里,用快捷键看一下Threa的状态,如图:

所以,线程的状态是有这几种的:

  • NEW(初始):也即新建一个线程对象,这个过程还没调用start方法
Thread t = new Thread(() -> 
   System.out.println(Thread.currentThread().getName());
);
System.out.println("创建线程后状态:" + t.getState());

创建线程后状态::NEW

  • RUNNABLE(运行):Java线程池中将(ready)就绪和(running)运行中两种状态统称为RUNNABLE,线程调用了start就会放在线程池中,处于就绪ready状态,等到分配到时间片后才变为运行runing状态
Thread t = new Thread(() -> 
   System.out.println(Thread.currentThread().getName());
);
t.start();
 System.out.println("Thread.start()之后的状态:" + t.getState());

Thread.start()之后的状态:RUNNABLE

  • BLOCKED(阻塞):表示线程阻塞于锁。线程抢不到锁就会出现这种状态
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抢到锁

  • WAITING(等待):WAITING状态,线程进入等待状态
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

  • TIMED_WAITING(超时等待):这种timed_awiting不同于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

  • TREMINATED(终止):这个状态表示线程已经执行完成

这种情况,可以用Thread.sleep,等到线程执行完成就会打印出来

问题9、线程状态的转换

问题10、Runnable和Callable对象是线程?

Thread才是线程对象,Runable和Callable可以理解为线程任务,需要开发者自己去实现接口

java并发编程系列之二线程基础

上篇文章对并发的理论基础进行了回顾,主要是为什么使用多线程、多线程会引发什么问题及引发的原因,和怎么使用Java中的多线程去解决这些问题。正所谓,知其然知其所以然,这是学习一个知识遵循的原则。推荐读者先行... 查看详情

并发编程系列之如何正确使用线程池?(代码片段)

并发编程系列博客并发编程系列之如何正确使用线程池?在上一章节的学习中,我们掌握了线程的基本知识,接着本博客会继续学习多线程中的线程池知识1、线程是不是越多越好?在学习多线程之前,读者可... 查看详情

并发编程之协程(代码片段)

...、gevent模块 1??协程介绍  1、前言+回顾    1.1并发的本质       基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态... 查看详情

重点知识学习(8.1)--[回顾线程知识,初探并发编程知识](代码片段)

文章目录1.回顾线程知识2.初探并发编程1.回顾线程知识JavaSE基础(十一)—<线程(1)>【线程概述,创建线程,以及线程的方法,优先级,状态,用户线程,守护线程】JavaSE基础(十一)–<线程(2)>【线程同步,死锁,Lock锁,线... 查看详情

并发编程系列之threadlocal实现原理(代码片段)

并发编程系列之ThreadLocal实现原理ThreadLocal看词义,线程本地变量?线程的变量,要怎么定义?怎么使用?ThreadLocal是线程安全的?下面给出一个简单例子,引出本文1、变量的作用域?局部变量(线程安全)publicclassAvoiddoSome1()inta... 查看详情

并非编程系列之创建线程的方法有多少种?(代码片段)

并非编程系列之创建线程的方法有多少种?并发多线程的知识是很重要而且比较杂的知识点,所以需要花不少时间用于整理。创建线程的方式是学习并发编程的一个很基础的问题,所以必须先掌握好1、创建线程的方... 查看详情

go语言系列之并发编程(代码片段)

Go语言中的并发编程并发与并行并发:同一时间段内执行多个任务(你在用微信和两个女朋友聊天)。并行:同一时刻执行多个任务(你和你朋友都在用微信和女朋友聊天)。Go语言的并发通过goroutine实现。goroutine类似于线程,... 查看详情

并发编程系列之futuretask源码学习笔记(代码片段)

并发编程系列之FutureTask源码学习笔记1、什么是FutureTask类?在上一章节的学习中,我们知道了Future类的基本用法,知道了Future其实就是为了监控线程任务执行的,接着本博客继续学习FutureTask。然后什么是FutureTask类?Future是1.5版... 查看详情

java并发编程之美之并发编程线程基础(代码片段)

什么是线程  进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程的一个执行路径,一个进程至少有一个线程,进程的多个线程共享进程的资源。  java启动main函数其实就是启动... 查看详情

spark系列(代码片段)

...《JVM性能优化》,《Spring核心知识》《Docker教程》和《Spark基础知识》,都是多年面试总结。欢迎关注【后端精进之路】,轻松阅读全部文章。Java并发编程:Java并发编程系列-(1)并发编程基础Java并发编程系列-(2)线程的并发工具类J... 查看详情

并发编程系列之callable和runnable的不同?(代码片段)

...nable和Callable的不同ps:基于Jdk1.8看源码1、Runnable入门实例并发编程系列之Callable和Runnable的不同?在学习并发多线程的过程中,很多读者都知道怎么实现Runnable,下面是一道经典的例子publicstaticvoidmain(String[]args) Threadt=newThread 查看详情

并发编程之携程(代码片段)

协程介绍一引子本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态cpu正在运行一个任务,会在两种情况下切走去执行其... 查看详情

并发编程之协程(代码片段)

引言 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态cpu正在运行一个任务,会在两种情况下切走去执行其他的任... 查看详情

并发编程系列之futuretask源码学习笔记(代码片段)

并发编程系列之FutureTask源码学习笔记1、什么是FutureTask类?在上一章节的学习中,我们知道了Future类的基本用法,知道了Future其实就是为了监控线程任务执行的,接着本博客继续学习FutureTask。然后什么是FutureTask... 查看详情

spark系列(代码片段)

目前已经更新完《Java并发编程》,《Spring核心知识》《Docker教程》和《JVM性能优化》,都是多年面试总结。欢迎关注【后端精进之路】,轻松阅读全部文章。Java并发编程:Java并发编程系列-(1)并发编程基础Java并发编程系列-(2)线... 查看详情

并发编程之协程(代码片段)

一,引子本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态cpu正在运行一个任务,会在两种情况下切走去执行其他的任... 查看详情

并发编程系列之如何正确使用线程池?

并发编程系列博客并发编程系列之如何正确使用线程池?在上一章节的学习中,我们掌握了线程的基本知识,接着本博客会继续学习多线程中的线程池知识1、线程是不是越多越好?在学习多线程之前,读者可能会有疑问?如果... 查看详情

java并发编程:多线程与并发原理回顾(代码片段)

今天来聊一聊经典的Java技术,并发编程。并发是程序的灵魂,一个优秀的Java程序一定会支持高并发,并且,并发编程也是面试环节中经常会问到的一个问题,那么今天我们以一道经典的Java面试题回顾一下Java... 查看详情