当前位置: 首页 > news >正文

java多线程笔记1

核心概念:

(1)进程包含线程

(2)进程是系统资源分配的最小单位;

    线程是系统调度执行的最小单位;

一.创建线程的方法

(1)继承Thread,重写run.通过Thread实例start启动线程;

public class demo1 {public static void main(String[] args) {MyThread t = new MyThread();t.start();while(true) {System.out.println("hello main!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

(2)实现Runnable,重写run.通过Thread的实例,把Runnable的实例传进去,再调用start;


class MyRunnable implements Runnable{@Overridepublic void run() {while(true) {System.out.println("hello thread!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
public class demo2 {public static void main(String[] args) {MyRunnable myRunnable = new MyRunnable();Thread t = new Thread(myRunnable);t.start();while(true) {System.out.println("hello main!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

(3)通过匿名内部类的方式来编写,本质上是(1);

public class demo3 {public static void main(String[] args) {Thread t = new Thread() {@Overridepublic void run() {System.out.println("hello thread!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}};t.start();while(true) {System.out.println("hello main!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

(4)通过匿名内部类的方式来编写,本质上是(2);

public class demo4 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(new Runnable() {@Overridepublic void run() {while(true) {System.out.println("hello Thread!");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}});t.start();while(true) {System.out.println("hello main!");Thread.sleep(1000);}}
}

(5)基于lambda表达式创线程;(推荐)

public class demo5 {public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while(true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();while(true) {System.out.println("hello main");Thread.sleep(1000);}}
}

注意:

(1)代码中创建的new Thread对象的生命周期和内核中实际的线程是不一定一样的,

可能会出现Thread对象存在但是内核中的线程不存在的情况,但是不会存在相反的情况;

(2)start和run的差别:

run:描述了线程要执行的任务,也可以称为线程的入口;

start:调用系统函数,真正在系统内核中,创建线程(创建PCB,加入到链表中),会根据不同的系统调用不同的api,创建好线程之后再来执行run;

(3)不一定非得main线程调用其他线程,其他线程也能调用新线程;

(4)一个Thread对象只能调用一次start;(一个对象只能对应一个线程);

如果Thread对象没有start,此时状态为NEW状态,若start过后则为非NEW状态;

补充概念:

变量捕获:将变量和lambda表达式定义在同一作用域当中,此时lambda内部是可以访问到lambda外部(和lambda同一作用域)的变量的;

Java中变量捕获的特殊要求(C++,JS等语言中没有这种要求):捕获的变量得是final/事实final;

lambda表达式本质上是一个"函数式接口"产生的匿名内部类;

二.前台线程和后台线程

概念

后台线程(deamon守护线程):在线程执行过程中,不能阻止进程结束(即进程结束时,线程也会随之结束);

前台线程:在线程执行过程中,可以阻止进程结束;

注意:

(1)进程(前台线程)要结束,后台线程无力阻止;

(2)后台线程先结束了,也不影响前台线程的结束;

(3)一个进程中,可以有多个前台线程;

多线程的使用场景:

(1)CPU密集型

(2)IO密集型

三.中止线程

(1)通过共享的标记来进⾏沟通

public class demo6 {private static boolean isQuit = false;public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while(!isQuit) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();Thread.sleep(5000);System.out.println(t.isAlive());isQuit = true;Thread.sleep(1000);System.out.println(t.isAlive());}
}

(2)调⽤ interrupt() ⽅法来通知

注意:(1)当interrupt()方法被执行时会直接唤醒sleep();

(2)当sleep()被唤醒时,会清空标志位;

(3)因此想要结束循环必须在catch中加上break或者return语句;


http://www.mrgr.cn/news/24665.html

相关文章:

  • 随机数与随机数种子
  • 跨境电商热卖季:选品攻略与实战指南
  • 在 Java 中实现 Kafka Producer 的单例模式
  • 导师最看重什么?撰写任务书时需注意的关键要素!
  • 《企业实战分享 · SonarQube10.x 详细教程》
  • 视频合并实用教程分享,教你6个合并视频方法,不可错过!
  • 广播与组播,超时检测
  • 82.C语言中的内存布局2
  • 56 - I. 数组中数字出现的次数
  • git命令行基础常用指令
  • 训练 Vision Transformer 模型并运行推理
  • leetcode 994.腐烂的橘子
  • 算法设计(一)
  • Linux 信息安全:构建坚固的防御体系
  • Linux和C语言(Day11)
  • 2018年系统架构师案例分析试题五
  • WEB渗透权限维持篇-映像劫持
  • cat:显示文本内容
  • LINQ 和 LINQ扩展方法 (1)
  • 果蔬识别系统性能优化之路(四)