并发编程的一些概念(一)

书中自有颜如玉,书中自有黄金屋
接下来一段时间一边工作,一边跟书学习高并发,来提高自己的能力,充实自己的知识量

程序

程序是认为编写的程序或者某种方式自动生成的代码,能够保存到文件中,程序本身是静态的.如果要运行程序,则需要将程序加载到内存中,通过编译器或解释器将其编译成计算机能够理解的方式运行

进程与线程

**进城是操作系统进行资源分配的最小单位**,在一个进程中可以创建多个线程
**线程是比进程粒度更小的能够独立运行得基本单位**,也是cpu调度的最小单位,被称为轻量级的进程
在一个进程中可以创建多个线程,多个线程各自拥有独立的局部变量,线程和堆栈和程序计数器等,能够访问共享的资源

** 进程与线程的区别**

进程是操作系统分配资源的最小单位,进程是CPU调度的最小单位
一个进程中可以创建多个线程,一个线程只能属于一个进程
进程与进程之间是相互独立的,进程内部的线程之间并不完全独立,可以共享进程的堆内存,方法去内存和系统资源
进程上下文的切换要比线程的上下文切换慢得多
进程是存在地址空间的,而线程本身无地址空间,线程的地址空间是包含在进程中的
某个进程发生异常不会对其它进程造成影响,某个线程发生异常可能会对所在进程中的其他线程造成影响

线程组

线程组可以同时管理多个线程.在实际应用中,如果系统创建的线程比较多,创建的线程也比较多明确,就可以将具有相同功能的线程放到一个线程组中

线程组的使用

package com.lifly.threadGroup;

/**
 * @ClassName ThreadGroupTest
 * @Description TODO
 * @Author lifly
 * @Date 2022/7/5 21:21
 * @Version 1.0.0
 **/
public class ThreadGroupTest {
    public static void main(String[] args) {
        //创建线程组
        ThreadGroup threadGroup = new ThreadGroup("threadGroup");

        //创建线程1,并在线程中传入线程组和线程名称
        Thread thread1 = new Thread(threadGroup, () -> {
            String groupName = Thread.currentThread().getThreadGroup().getName();
            String threadName = Thread.currentThread().getName();
            System.out.println(groupName + ":" + threadName);
        }, "thread1");

        //创建线程2
        Thread thread2 = new Thread(threadGroup,()->{
            String groupName = Thread.currentThread().getThreadGroup().getName();
            String threadName = Thread.currentThread().getName();
            System.out.println(groupName + ":" + threadName);
        },"thread2");

        thread1.start();
        thread2.start();
    }
}

用户线程和守护线程

用户线程

用户线程是最常见的线程,比如在程序启动时,JVM调用程序的main()方法就会创建一个用户线程
创建用户线程
package com.lifly.userThread;

/**
 * @ClassName ThreadTest
 * @Description TODO
 * @Author lifly
 * @Date 2022/7/5 21:33
 * @Version 1.0.0
 **/
public class ThreadTest {
    public static void main(String[] args) {
        //创建用户线程
        Thread thread = new Thread(() -> {
            System.out.println("用户线程");
        }, "ThreadUser");
        
        thread.start();
    }
}

用户线程是一种特殊的线程,这种线程在系统后台完成相应的任务,例如JVM中的垃圾回收及线程,JIT编译线程都是守护线程
在程序运行的过程中,只要有一个非守护线程还在运行,守护线程就会一直运行,只有所有的非守护线程全部运行结束,守护线程才会退出.
在编写java程序时,可以手动指定当前线程是否是守护线程,直接调用Thread对象的setDeamon()方法,传入true即可.
以下代码是将线程设置为守护线程
package com.lifly.userThread;

/**
 * @ClassName ThreadTest
 * @Description TODO
 * @Author lifly
 * @Date 2022/7/5 21:33
 * @Version 1.0.0
 **/
public class ThreadTest {
    public static void main(String[] args) {
        //创建用户线程
        Thread thread = new Thread(() -> {
            System.out.println("守护线程");
        }, "ThreadUser");
        thread.setDaemon(true);
        thread.start();
    }
}

并发与并行

并行指多核CPU中的一个CPU核心执行线程时,另一个CPU核心能够同时执行另一个线程,两个线程不会抢占CPU资源,可以同时执行.
并发指在一段时间内CPU处理了多线程,这些线程会抢占CPU的资源,CPU资源根据时间片周期在多个线程之间来回切换,多个线程在同一段时间内同时运行,而在同一时刻实际不是同时运行的.

在这里插入图片描述
在这里插入图片描述
并行与并发的区别

并行之多个线程在一段时间的每个时刻都同时在运行,并发之多个线程在一段时间内(而非同一时刻)同时运行
并行执行的多个任务之间不会抢占CPU资源,并发执行的多个任务会抢占CPU资源
并行只有在多核CPU或者多CPU的情况下才会发生,在单核CPU中只可能发生串行执行或者并发执行

同步和异步

同步和异步主要是这对一次方法的调用来说的.已同步方式调用来说,必须在方法返回信息后,才能执行后面的操作.而以异步方式调用方法时,不必等方法返回信息,就可以执行后面的操作,当完成被调用的方法逻辑后,会以通知或者回调的方法告知调用方法

共享与独享

共享指多个线程在运行过程中共享某些资源,而独享指一个线程在运行过程中独占某个系统资源.
例如在java程序运行的过程中,JVM中的方法区和堆空间是线程共享的,而栈,本地方法和程序计数器是每个线程独占的,也就是独享的.

临界区

临界区一般表示能够被多个线程共享的资源或数据,但是每次只能提供给一个线程使用,临界区资源一旦被占用,其他线程就必须等待.
在并发编程中,临界区一般指受保护的对象或程序代码片段,可以通过加锁的方式保证每次只有一个线程进入临界区,从而达到保护临界区的目的

阻塞与非阻塞

阻塞与非阻塞一般用来描述多个线程之间的相互影响.例如,在并发编程中,多个线程抢占一个临界区资源,如果其中一个线程抢占成功,那么其他的线程必须阻塞等待.在占用临界区资源的线程执行完毕,释放临界区资源后,其他线程可以再次抢占临界区资源.
如果占用临界区资源的线程一直不释放资源,其他线程则会一直阻塞等待
非阻塞线程之间不会相互影响,所有的线程都会继续执行.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

double_lifly

点喜欢就是最好的打赏!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值