JUC前置知识

发布时间 2023-10-23 23:33:54作者: 长名06

JUC前置知识

JUC概述

在开发语言中,线程部分是重点,JUC是关于线程的。JUC是java.util.concurrent工具包的简称。这是一个处理线程的工具包,JDK1.5开始出现的。

线程和进程

线程和进程的概念
进程(process): 是计算机的程序关于某数据集合上的一次允许活动,是操作系统进行资源分配和任务调度的最小单位,是操作系统的基础。在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令,数据及其组织形式的描述,进程是程序的实体。
线程(thread): 是操作系统或CPU核心能够进行调度的最小单位。被包含在进程中,是进程中的实际运行单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以有多个线程,每个线程执行不同的任务。

总结

进程,是在系统中正在运行的一个应用程序,程序一旦运行就是进程,也是操作系统资源分配的最小单位。
线程,是CPU(Central Processing Unit缩写)核心(现代计算机的CPU可以有多个CPU核心,俗称的4核,8核等)进行资源调度的最小单位,或者说进程内独立执行的一个执行流单元,也是程序执行的最小单位。

线程的状态

线程状态类
public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
     	//新建
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
     	//准备就绪,可以运行
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
     	//阻塞
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
     	//等待,不见不散
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
     	//定时等待,过时不候
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
     	//停止,终止
        TERMINATED;
    }

wait和sleep方法的区别

  • 1.sleep是Thread类的静态方法,wait是Object类的方法,任何对象实例都能调用。
  • 2.sleep不会释放锁,也不需要占有锁。wait会释放锁,但释放锁这个动作的前提是,当前线程占有锁。
  • 3.这两个方法都可以被interrupted方法中断。
  • 4.这两个方法还有个特点,就是线程在哪里被阻塞,就在哪里被唤醒。
串行,并行和并发
串行模式

串行表示所有任务一一按先后顺序进行。串行意味着必须先装完一车柴才能运送这车柴,只有运送到了,才能卸下这车柴,并且只有完成了这三个步骤,才能进行下一步骤。串行是一次只能取得一个任务,并执行这个任务。

并行模式

并行意味着可以同时取得多个任务,,并同时去执行所取得的这些任务。并行模式相当于将长长的一条队列,划分成了多条短队列,所以并行缩短了任务队列的长度。并行的效率从代码层次上,强依赖于多进程/多线程代码,从硬件角度上依赖于多核CPU。

并发

指的是多个程序可以同时运行的现象,更细化的是多进程可以同时运行或者多指令可以同时运行。
并发的重点是一种现象,描述的是多进程同时运行的现象。但实际上,一个CPU同时,只能运行一个线程。所以同时运行,不是同一时刻有多个线程运行的现象,而是提供一种功能,让用户看起来多个程序同时运行了,但是实际上的线程不是一直霸占CPU的,而是执行一会停,一会执行。
要解决大并发问题,通常是将大任务分解成多个小任务,由于OS(Operating System)对进程的调度是随机的,所以切分成多个小任务后,可能会从任一小任务出执行。可能出现的问题,一个小任务执行了多次,还没开始下个任务。这时一般会采用队列或类似数据结构来存放各个小任务的成果。可能出现还没准备好第一步,就执行第二步的可能。这时,一般采用多路复用或异步的方式,比如只有准备好了,才产生事件执行下一步任务。可以多进程/多线程的方式并行执行这些小任务。也可以单进程/单线程执行这些小任务,这是很可能要配合多路复用才能达到较高的效率。

小结

并发:同一时刻多个线程在访问同一资源,多个线程对一个点。如春运抢票,电商秒杀。
并行:多项工作一起执行,之后再汇总。如泡泡面,水壶烧水,一边放调料。

管程

管程又叫Monitor(监视器),在OS中叫管程/Monitor(监视器),在Java中叫锁(Lock)。
锁其实是一种同步机制,保证同一时间内,只能有一个线程访问受保护的资源。
在JVM中实现这个锁机制(同步机制),是通过进入,退出管程对象实现的,也就是常说的持有锁,和释放锁。进入管程(拥有锁),退出管程(释放锁)。一个线程持有该锁,就只有当前线程可以访问,该锁保护的资源。释放锁,就是当前线程不访问,该锁保护的资源了,其他线程可以竞争该锁,谁获取到锁,可以访问锁保护的线程。

用户线程和守护线程

daemon n.守护神
用户线程和守护线程,是jvm中的概念。
用户线程,顾名思义,用户自定义的线程。主线程结束,用户线程还在运行,jvm存活。
守护线程 ,用于守护用户线程,执行的线程如垃圾回收(gc)。没有用户线程,都是守护线程的化话,主线程结束,jvm结束。设置一个线程为守护线程,必须在开启这个线程之前。

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t" + Thread.currentThread().isDaemon());// aa true
            while(true){

            }
        },"aa");
        thread.setDaemon(true);//通过该方法可将线程设置为守护线程
        thread.start();

        System.out.println(Thread.currentThread().getName() + "over");// mainover
    }
}

只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。