JavaEE----多线程

目录

 认识线程

概念:

为啥要有线程:

进程和线程的区别:

多线程的优势和缺陷:

 线程的状态:

Thread:线程

创建线程: 

线程的启动

 线程的属性:

Thread中常用的方法:

join()等待

currentThread() 当前线程

sleep()休眠

线程的中断 


认识线程

概念:

一个线程就是一个 "执行流". 每个线程之间都可以按照顺讯执行自己的代码. 多个线程之间 "同时" 执行着多份代码.

为啥要有线程:

首先, "并发编程" 成为 "刚需”;

  • 单核 CPU 的发展遇到了瓶颈. 要想提高算力, 就需要多核 CPU. 而并发编程能更充分利用多核 CPU资源。
  • 有些任务场景需要 "等待 IO", 为了让等待 IO 的时间能够去做一些其他的工作, 也需要用到并发编程。

其次, 虽然多进程也能实现 并发编程, 但是线程比进程更轻量;

进程:系统分配资源的最小单位,系统以时间片轮转调度的方式来执行
时间片轮转调度:并发的,需要保存上下文信息

简单说线程就是轻量级进程:相比进程,创建、调度、销毁效率要高很多。

进程和线程的区别:

  1. 进程是包含线程的. 每个进程至少有一个线程存在,即主线程。
  2. 进程和进程之间不共享内存空间. 同一个进程的线程之间共享同一个内存空间。 
  3. 进程是系统分配资源的最小单位,线程是系统调度的最小单位。(系统调度:由CPU执行进程的代码指令)
  4. 线程的创建,销毁代价比进程小(状态转换进程的开销大于线程)
  5. 线程有bug可能会造成整个进程挂掉;进程间是独立运行的。

多线程的优势和缺陷:

优势:

  1. 充分利用CPU资源,提高执行效率
  2. io等阻塞时能同时接收输入

缺陷:

  1. 线程的创建/销毁也是具有一定的系统开销(一般用于执行耗时比较长的任务)
  2. 会增加编码的复杂程度

 线程的状态:

new:创建态

runnable:可运行态

waiting:等待 

timed_waiting:超时等待

blocked:阻塞

terminated:终止

Thread:线程

创建线程:
 

(1)继承Thread(要重写run方法,定义要执行的任务代码) 

class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println("这里是线程运行的代码");
        }
    }

继承 Thread 类, 直接使用 this 就表示当前线程对象的引用. 

(2)实现Runnable接口(也要重写run方法)

public static void main(String[] args) {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("这里是线程执行的代码");
            }
        });
        t.start();//线程启动
    }

实现 Runnable 接口, this 表示的是 MyRunnable 的引用 需要使用 Thread.currentThread() 

(3)实现Callable接口

(获取线程执行的结果) 

线程的启动

thread.start() => 申请系统调度,执行thread中的任务(重写run方法)

thread中,start() 和 run() 有什么区别?

start:启动线程的方式

run:属于线程任务的描述

 多个线程,同时存在并发并行的情况

并发:一个CPU以时间片轮转调度的方式,执行多个线程,给我们感觉像在同时执行

并行:多个CPU在一个时间点,同时执行多个进程

 线程的属性:

 public static void main(String[] args) {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类run");
            }
        },"线程名");
        t.start();
        System.out.println(t.getName());//获取线程名称
        System.out.println(t.getState());//获取线程状态
        System.out.println(t.isDaemon());//是否是后台线程
        System.out.println(t.isAlive());//是否存活:如果启动后销毁前,都是存活
    }

关于后台线程只要记住:JVM会在一个进程的所有非后台线程结束后,才会结束运行。

是否存活,即简单的理解,为 run 方法是否运行结束了。

Thread中常用的方法:

join()等待

 当前线程(t.join在哪个线程执行,就是谁)等待,直到线程引用执行完毕

当前线程等待,最多等待给定的毫秒数,或者线程引用对象死亡

使用join后,两个线程从并发并行随机执行的方式,就变为有一定顺序

currentThread() 当前线程

 返回当前线程的引用对象

sleep()休眠

让当前线程休眠(超时等待)给定时间

线程的中断 

使用注意事项:

  1. java中断,是以中断标志位的方式来执行
  2. interrupt是发起中断的动作,但线程是否中断,由自己代码是否判断标志位来决定 
  3. 线程如果处于某些等待/超时等待(会抛InterruptedException),是允许的

中断的方式是:抛异常来中断,抛异常以后,会重置/还原中断标志位

如果线程因为调用wait、join、sleep 等方法而挂起,则以InterruptedException异常的形式通知,清除中断标志,当出现这个异常的时候,要不要结束线程取决于catch中代码的写法,可以选择忽略这个异常,也可以跳出循环结束线程。Thread.interrupted() 判断当前线程的中断标志被设定,清除中断标志Thread.currentThread().isInterrupted()判断指定线程的中断标志被设置,不清除中断标志,这种方式通知收到的更及时,即使线程正在sleep也可以马上收到。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值