Java并发 day01进程和线程 、并行和并发、 java线程

进程和线程

进程

1、程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理 IO 的(管理资源)
2、当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。
3、进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程,也有的程序只能启动一个实例进程

线程

1、一个进程之内可以分为一到多个线程。 一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给 CPU 执行
2、Java中,线程作为最小调度单位(CPU从线程获取指令),进程作为资源分配的最小单位(管理资源)。 在 windows 中进程是不活动的,只是作为线程的容器
3、线程是由一些列指令组成的。

二者对比

1、进程基本上相互独立的,而线程存在于进程内,是进程的一个子集
2、进程拥有共享的资源,如内存空间等,供其内部的线程共享
3、进程间通信较为复杂
同一台计算机的进程通信称为 IPC(Inter-process communication)
不同计算机之间的进程通信,需要通过网络,并遵守共同的协议,例如 HTTP
4、线程通信相对简单,因为它们共享进程内的内存,一个例子是多个线程可以访问同一个共享变量
5、线程更轻量,线程上下文切换成本一般上要比进程上下文切换低

并行和并发

并发

单核CPU,线程是串行执行的。操作系统中有一个组件叫做任务调度器,将CPU的时间片(windows下时间片最小约为15毫秒)分给不同的线程使用,只是由于CPU在线程间的切换非常快。(微观串行,宏观并行)
线程轮流使用CPU就是并发,concurrent。

并行

多核 cpu下,每个 核(core) 都可以调度运行线程,这时候线程可以是并行的,也可以是并发的。

两者对比

并发(concurrent)是同一时间应对(dealing with)多件事情的能力(单核)
并行(parallel)是同一时间动手做(doing)多件事情的能力(多核)

java线程

创建线程

创建线程–方法1 继承Thread类(重写run)
创建线程–方法2 实现Runnable接口(重写run)
创建线程–方法3 FutureTask实现Callable(间接实现Runable接口,有返回值)

FutureTask:

        FutureTask<Integer> futureTask = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                return 100;
            }
        });
        Thread t3 = new Thread(futureTask, "t3");
        t3.start();
        Integer i = futureTask.get();
        System.out.println(i);

查看进程和线程

在这里插入图片描述

tasklist | findstr java
taskkill /F /PID 进程编号

在这里插入图片描述

ps -aux | grep 进程PID
kill -9 进程PID

在这里插入图片描述

jconsole 远程监控配置

-Djava.rmi.server.hostname=ip地址 -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=连接端口 -Dcom.sun.management.jmxremote.ssl=是否安全连接 -Dcom.sun.management.jmxremote.authenticate=是否认证 java类

线程运行原理

栈(stack)和栈帧(Frame)

每个线程启动后,虚拟机会为其分配一块栈内存
每个栈由多个栈帧组成,对应着每次方法调用时占用的内存
每个线程只能有一个活动栈帧,对应着当前正在执行的方法。

线程上下文切换(Thread Context Switch)

导致CPU不再执行当前线程,转而执行另一个线程的代码的原因:
1、线程的CPU时间片用完
2、垃圾回收(会暂停其他线程)
3、有优先级更高的线程
4、线程自己调用了sleep、yield、wait、join、synchronized等方法

Context Switch发生时,需要有操作系统保存当前线程的状态,并恢复另一个线程的状态,java中对应的概念就是程序计数器,它的作用是记住吓一跳JVM指令的执行地址和,是线程私有的。
1、状态包括程序计数器、虚拟机栈中每个栈帧的信息,如局部变量、操作数栈、返回地址等
2、Context Switch 频繁发生会影响性能。

常见方法

在这里插入图片描述

start是开启线程
run是执行线程中的方法。
直接调用 run 是在主线程中执行了 run,没有启动新的线程
使用 start 是启动新的线程,通过新的线程间接执行 run 中的代码

在这里插入图片描述

join(long n)有时效的等待,如果超过时间,就不会再继续等待。
join的底层原理就是wait()

在这里插入图片描述

在这里插入图片描述

sinterrupted()判断是否被打断,不会清除标记
interrupted()判断是否被打断,会清除标记

在这里插入图片描述

对于正常运行的线程,打断线程并不能让线程停止,需要借助打断标记打断
park 线程, 不会清空打断状态,一般和interrupted()清除标记一起使用
LockSupport.park();

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread("t1"){
            @Override
            public void run() {
                while (true){
                    if(Thread.currentThread().isInterrupted()){
                        log.debug("打断");
                        break;
                    }
                }
            }
        };
        t1.start();
        t1.interrupt();
    }

在这里插入图片描述

sleep

1、调用 sleep 会让当前线程从 Runnable 进入 Timed Waiting 状态(阻塞)
2、其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException
3、睡眠结束后的线程未必会立刻得到执行
4、防止CPU占用100%
5、建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性
TimeUnit.SECONDS.sleep(1);

yield(让出)

1、调用 yield 会让当前线程从 Running 进入 Runnable 就绪状态,然后调度执行其它线程
2、具体的实现依赖于操作系统的任务调度器

在这里插入图片描述

守护线程

默认情况下,Java进程需要等待所有线程都运行结束,才会结束。有一种特殊的线程叫做守护线程,只要其它非守护线程运行结束了,即使守护线程的代码没有执行完,也会强制结束。

@Slf4j(topic = "c.test")
public class Thread4 {
    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread("t1"){
            @SneakyThrows
            @Override
            public void run() {
                log.debug("start");
                Thread.sleep(2000);
                log.debug("end");
            }
        };
        t1.setDaemon(true);
        t1.start();
        Thread.sleep(1000);
        log.debug("main");
    }
}

垃圾回收器线程就是一种守护线程
Tomcat 中的 Acceptor 和 Poller 线程都是守护线程,所以 Tomcat 接收到
shutdown 命令后,不会等待它们处理完当前请求

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

halulu.me

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值