JAVA多线程总结

一、概念:
1、什么是多任务
      多任务就是在同一时间做多件事情,如边吃饭边玩手机等。看起来是多个任务都在做,本质上我们的大脑在同一时间依旧只做了一件件事情

2、什么是程序
      程序是指令和数据的有序集合,其本身没有任何运行含义,是一个静态概念

3、什么叫进程
       进程是执行程序的一次过程,它是一个动态概念,是系统资源分配的单位

小结:通常在一个进程是包含若干个线程,进程中至少有一个线程,不然没有存在的意义,线程是cpu调度和执行的单位

注:很多线程是我们模拟出来的,真是的线程是只多个cup,即多核。如果模拟出来的多线程,即在一个cpu的情况下,在同一个时间的点,cpu只能执行一个代码,因为切换的很快,所以就会有同时执行的错觉

 4、多线程
只有主线程的时候:

开启多线程的时候:

5、多线程的核心概念
1)、线程就是独立的执行路径

2)、在程序运行时,即使自己没有创建多线程,后台也会有很多线程

3)、main()称为主线程,为系统的入口,用于执行整个程序

4)、在一个进程中,如果开辟了多个线程,线程的运行和调度由调度器安排调度,调度器与操作系统紧密相关,先后顺序是不能人为干预的。

5)、对同一份资源操作时,会存在资源抢夺问题,需要加并发控制

6)、线程会带来额外的开销,如cup的调度时间,并发控制等

7)、每个线程正在自己的工作内存交互,内存控制不当会造成数据不一

 二、多线程的创建

Thread class继承Thread
Runnable Interface实现Runnable接口
Callable Interface实现Callable接口(了解)

1、自定义线程类,继承Thread类,

     重写run()方法,编写线程体,

     创建线程对象,调用start()方法启动线程

 
  1. package com.demo01;

  2. // 多线程 继承Thread

  3. public class TestThread01 extends Thread{

  4. public static void main(String[] args) {

  5. for(int i = 0; i<20; i++){

  6. System.out.println(i+"我正在学习多线程");

  7. }

  8. TestThread01 t = new TestThread01();

  9. t.start();

  10. }

  11. @Override

  12. public void run(){

  13. for(int i=0;i<20;i++){

  14. System.out.println(i+"开启多线程");

  15. }

  16. }

  17. }

注:线程开启不一定马上执行,由cpu调度

2、实现Runnable接口

     自定义类实现Runnable接口

     重写run()方法,编写线程执行体

     创建线程对象,调用start()方法启动线程体

 
  1. package com.demo01;

  2. //第二种实现Thread的方法 实现Runnable接口

  3. public class TestThread02 implements Runnable{

  4. @Override

  5. public void run(){

  6. for(int i = 0;i < 20; i++){

  7. System.out.println(i+"我在学习多线程");

  8. }

  9. }

  10. public static void main(String[] args) {

  11. for(int i =0;i<20;i++){

  12. System.out.println(i+"正在学习多线程");

  13. }

  14. TestThread02 t1 = new TestThread02();

  15. Thread thread = new Thread(t1);

  16. thread.start();

  17. }

  18. }

3、实现Callable接口(了解)

 
  1. package com.demo01;

  2. import java.util.concurrent.*;

  3. //创建线程 实现Callable接口

  4. public class TestThread05 implements Callable<Boolean> {

  5. @Override

  6. public Boolean call() throws Exception {

  7. for(int i=1;i<=10;i++){

  8. System.out.println("我正在学习"+i);

  9. }

  10. return true;

  11. }

  12. public static void main(String[] args) throws ExecutionException, InterruptedException {

  13. TestThread05 t = new TestThread05();

  14. // 创建执行服务

  15. ExecutorService ser = Executors.newFixedThreadPool(1);

  16. // 提交执行

  17. Future<Boolean> submit = ser.submit(t);

  18. // 获取结果集

  19. Boolean aBoolean = submit.get();

  20. // 关闭服务

  21. ser.shutdownNow();

  22. }

  23. }

小结:

  1. 继承Thread类    继承Runnable接口
  2. 子类继承Thread类具备多线程能力    实现Runnable接口具备多线程能力
  3. 启动线程:子类对象.start()    启动线程:传入目标对象+Thread对象.start()
  4. 不建议使用:避免oop单继承的局限性    
  5. 推荐使用:避免单继承的局限性,

同一个对象可以被多个线程使用
三、线程的状态

 1)、线程停止

建议线程正常停止-->利用次数,不建议死循环

建议使用标志位-->设置一个标志位

 
  1. package com.StateThread;

  2. //线程的状态

  3. //使线程停止

  4. public class TestThread06 implements Runnable{

  5. private boolean flag = true;

  6. @Override

  7. public void run() {

  8. int i = 0;

  9. while (flag){

  10. System.out.println("线程运行中"+i++);

  11. }

  12. }

  13. // 标志位

  14. public void stop(){

  15. this.flag=false;

  16. }

  17. public static void main(String[] args) {

  18. TestThread06 t = new TestThread06();

  19. new Thread(t).start();

  20. for(int i=0;i<1000;i++){

  21. System.out.println(i);

  22. if(i==900){

  23. System.out.println("线程停止了"+i);

  24. t.stop();

  25. }

  26. }

  27. }

  28. }

2)、线程休眠

 
  1. package com.StateThread;

  2. //模拟线程休眠

  3. public class TestThread07 implements Runnable{

  4. public static void main(String[] args) {

  5. TestThread07 t = new TestThread07();

  6. new Thread(t).start();

  7. }

  8. @Override

  9. public void run() {

  10. int sum = 10;

  11. while (true){

  12. try {

  13. Thread.sleep(1000);

  14. } catch (InterruptedException e) {

  15. e.printStackTrace();

  16. }

  17. System.out.println(sum--);

  18. if(sum==0){

  19. break;

  20. }

  21. }

  22. }

  23. }

注:每一个对象都有一个锁,sleep不会释放锁,Thread.sleep(1000) 1千毫米=1秒

3)、线程礼让

 
  1. package com.StateThread;

  2. //线程礼让

  3. public class TestThread08 implements Runnable{

  4. @Override

  5. public void run() {

  6. System.out.println(Thread.currentThread().getName()+"线程执行开始");

  7. Thread.yield();

  8. System.out.println(Thread.currentThread().getName()+"线程执行结束");

  9. }

  10. public static void main(String[] args) {

  11. TestThread08 t = new TestThread08();

  12. new Thread(t,"小明").start();

  13. new Thread(t,"小红").start();

  14. }

  15. }

注:礼让不一定会成功,要看cpu的心情 Thread.yieId()。

4)、线程插队

Join合并线程,待线程执行完成后再执行其他线程,其他线程阻塞。可以想象成插队。Thread.join()。

 
  1. package com.StateThread;

  2. //线程插队

  3. public class TestThread09 implements Runnable{

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

  5. TestThread09 t = new TestThread09();

  6. Thread thread = new Thread(t);

  7. thread.start();

  8. for (int i =0;i<500;i++){

  9. if(i==200){

  10. thread.join();

  11. }

  12. System.out.println("main执行"+i);

  13. }

  14. }

  15. @Override

  16. public void run() {

  17. for(int i =0;i<500;i++){

  18. System.out.println("子线程执行VIP"+i);

  19. }

  20. }

  21. }

5)、观察线程状态

Thread.state()。

 
  1. //观察线程状态

  2. public class TestThread10 {

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

  4. Thread t = new Thread(()->{

  5. for(int i=0;i<5;i++){

  6. try {

  7. Thread.sleep(1000);

  8. } catch (InterruptedException e) {

  9. e.printStackTrace();

  10. }

  11. }

  12. System.out.println("结束");

  13. });

  14. // 线程启动前的状态

  15. Thread.State state = t.getState();

  16. System.out.println(state);

  17. // 线程启动时的状态

  18. t.start();

  19. state = t.getState();

  20. System.out.println(state);

  21. // 线程结束时的状态

  22. while (state != Thread.State.TERMINATED){//只要线程不中止

  23. Thread.sleep(100);

  24. state = t.getState();

  25. System.out.println(state);

  26. }

  27. }

  28. }

6)、线程优先级

线程优先级用数字表示范围从1~10,数字越大优先级越大

要先设置优先级在启动线程

 
  1. package com.StateThread;

  2. //线程的优先级

  3. public class TestThread11 {

  4. public static void main(String[] args) {

  5. System.out.println(Thread.currentThread().getName()+"->"+Thread.currentThread().getPriority());

  6. test t = new test();

  7. Thread t1 = new Thread(t);

  8. Thread t2 = new Thread(t);

  9. Thread t3 = new Thread(t);

  10. Thread t4 = new Thread(t);

  11. Thread t5 = new Thread(t);

  12. // 1

  13. t1.start();

  14. // 2

  15. t2.setPriority(Thread.MAX_PRIORITY);

  16. t2.start();

  17. // 3

  18. t3.setPriority(Thread.MIN_PRIORITY);

  19. t3.start();

  20. // 4

  21. t4.setPriority(6);

  22. t4.start();

  23. // 5

  24. t5.setPriority(8);

  25. t5.start();

  26. }

  27. }

  28. class test implements Runnable{

  29. @Override

  30. public void run() {

  31. System.out.println(Thread.currentThread().getName()+"->"+Thread.currentThread().getPriority());

  32. }

  33. }

注:优先级只是意味着获得调度的概率低,并不是优先级低就不会被调度或被晚调度,这都看cpu的心情,人为是没办法干预cpu的调度的

7)、守护线程

 1、线程分为用户线程和守护线程

 2、虚拟机必须确保用户线程执行完毕(main(主线程))

 3、虚拟机不用等待守护线程执行完毕(gc(垃圾回收))

设置方法为: Thread.setPaemon(ture) 默认为:false

 
  1. package com.StateThread;

  2. //守护线程

  3. public class TestThread12 {

  4. public static void main(String[] args) {

  5. test1 t1 = new test1();

  6. test2 t2 = new test2();

  7. Thread th = new Thread(t2);

  8. th.setDaemon(true);

  9. th.start();

  10. new Thread(t1).start();

  11. }

  12. }

  13. class test1 implements Runnable{

  14. @Override

  15. public void run() {

  16. for (int i=0;i<36500;i++){

  17. System.out.println("我一直开心的活着");

  18. }

  19. System.out.println("和这个时间说再见了");

  20. }

  21. }

  22. class test2 implements Runnable{

  23. @Override

  24. public void run() {

  25. while (true){

  26. System.out.println("上帝一直保佑着我");

  27. }

  28. }

  29. }

四、线程同步
 1、概念:

线程同步其实就是一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,前面线程使用完毕,下一个线程在使用。

2、什么是并发:

多个线程操作同一个资源。

3、锁:

每一个对象都有一把锁,解决安全问题。

4、形成条件:

队列+锁

5、同步方法

这套机制就是synchronized关键字,包括两种方法,synchronized方法和synchronized块

缺陷:将一个方法神明为synchronized将会影响效率
 

 
  1. package com.Synchrohized;

  2. public class UnSafeTicket {

  3. public static void main(String[] args) {

  4. ticket t =new ticket();

  5. new Thread(t,"1").start();

  6. new Thread(t,"2").start();

  7. new Thread(t,"3").start();

  8. }

  9. }

  10. //多线程

  11. class ticket implements Runnable{

  12. private boolean flag = true;

  13. private int ticket=100;

  14. @Override

  15. public void run() {

  16. while (flag){

  17. try {

  18. Thread.sleep(100);

  19. buyTicket();

  20. } catch (InterruptedException e) {

  21. e.printStackTrace();

  22. }

  23. }

  24. }

  25. //线程停止

  26. public void stop() {

  27. this.flag = false;

  28. }

  29. //买票

  30. public synchronized void buyTicket() throws InterruptedException {

  31. if(ticket<=0){

  32. stop();

  33. return;

  34. }

  35. System.out.println(Thread.currentThread().getName()+"买到了第"+ticket--+"张票");

  36. }

  37. }

 
  1. //synchronized代码块的使用

  2. package com.Synchrohized;

  3. public class UnSafeBank {

  4. public static void main(String[] args) {

  5. Account account = new Account(1000,"存款");

  6. people people = new people(account,50);

  7. people people1 = new people(account,100);

  8. people.start();

  9. people1.start();

  10. }

  11. }

  12. class people extends Thread{

  13. Account account;

  14. int quMoney;

  15. int nowMoney;

  16. public people(Account account,int quMoney){

  17. this.account=account;

  18. this.quMoney=quMoney;

  19. }

  20. //取钱

  21. @Override

  22. public void run(){

  23. synchronized (account){

  24. if(account.money-quMoney<0){

  25. System.out.println("钱不够,取不了");

  26. return;

  27. }

  28. try {

  29. Thread.sleep(1000);

  30. } catch (InterruptedException e) {

  31. e.printStackTrace();

  32. }

  33. account.money = account.money-quMoney;

  34. nowMoney = nowMoney + quMoney;

  35. System.out.println(account.name+"余额为"+account.money);

  36. System.out.println(this.getName()+"手上的钱为"+nowMoney);

  37. }

  38. }

  39. }

  40. //账户

  41. class Account{

  42. int money;

  43. String name;

  44. public Account(int money, String name) {

  45. this.money = money;

  46. this.name = name;

  47. }

  48. }

五、死锁

    1、死锁的概念:

多个线程个占用一些资源,并且等待其他线程占有的资源才能运行,而导致两个或多个线程都在等待对象释放资源。都停止执行的情形,某一个同步块同时拥有 两个以上对象的锁时就可能发生死锁的问题

总结:多个线程互相抱着对方需要的资源,然后形成僵持。

 
  1. package com.Lock;

  2. public class DieLock {

  3. public static void main(String[] args) {

  4. test t = new test(0,"小明");

  5. test t1 = new test(1,"小红");

  6. t.start();

  7. t1.start();

  8. }

  9. }

  10. //手机

  11. class phone{

  12. }

  13. //电脑

  14. class computer{

  15. }

  16. //多线程

  17. class test extends Thread{

  18. // 需要资源只有一份需要static来保证

  19. static phone p = new phone();

  20. static computer c = new computer();

  21. // 选择

  22. int choice;

  23. // 名称

  24. String name;

  25. public test(int choice,String name){

  26. this.choice=choice;

  27. this.name=name;

  28. }

  29. @Override

  30. public void run(){

  31. game();

  32. }

  33. // 选择玩什么

  34. public void game(){

  35. if(choice==0){

  36. synchronized(p){

  37. System.out.println("我正在玩电脑");

  38. synchronized (c){

  39. System.out.println("我想玩手机");

  40. }

  41. }

  42. }else

  43. {

  44. synchronized (c){

  45. System.out.println("我正在玩手机");

  46. synchronized (p){

  47. System.out.println("我想玩电脑");

  48. }

  49. }

  50. }

  51. }

  52. }

六、Lock(锁)

    从JDK5.0开始,java提供了更强大的线程同步机制----通过显示定义同锁对象来实现。同步锁使用Lock对象充当。

  ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,在实现线程安全中,比较常用的是ReentrantLock,可以显示加锁和释放锁。
 

 
  1. package com.Lock;

  2. //Lock锁

  3. public class ReentrantLock {

  4. public static void main(String[] args) {

  5. TestLock testLock = new TestLock();

  6. new Thread(testLock,"1").start();

  7. new Thread(testLock,"2").start();

  8. new Thread(testLock,"3").start();

  9. }

  10. }

  11. class TestLock implements Runnable{

  12. private int ticketNum=10;

  13. // 定义Lock锁

  14. private final java.util.concurrent.locks.ReentrantLock lock = new java.util.concurrent.locks.ReentrantLock();

  15. @Override

  16. public void run() {

  17. while (true) {

  18. try {

  19. // 加锁

  20. lock.lock();

  21. if (ticketNum > 0) {

  22. Thread.sleep(1000);

  23. System.out.println(Thread.currentThread().getName()+"-----"+ticketNum--);

  24. }else {

  25. break;

  26. }

  27. } catch (InterruptedException e) {

  28. e.printStackTrace();

  29. } finally {

  30. // 解锁

  31. lock.unlock();

  32. }

  33. }

  34. }

  35. }

Lock是显示锁(手动开启和关闭锁)

Synchronized是隐式锁,出了作用域自动释放

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/176115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

洗地机应该怎么选?希亦、必胜、米博、添可、小米洗地机实测推荐

作为一个常年测评智能家居的博主&#xff0c;关于洗地机的测评使用这些年也积累了不少的体验感受。以至于常被周边的朋友问到&#xff0c;洗地机到底是不是真的好用&#xff1f;洗地机有什么优点吗&#xff1f;选购的时候应该怎么选呢&#xff1f;洗地机什么牌子比较好呢&#…

chatglm3 vllm部署推理;api访问使用

用fastchat部署暂时有各种问题,参考:https://github.com/lm-sys/FastChat/pull/2622 本篇用vllm运行测试可以使用 1、vllm运行 python -m vllm.entrypoints.api_server --model /***/chatglm/chatglm3-6b/

【C语言】深入理解数据类型转换与运算

文章目录 1.数据类型转换在分析源程序之前&#xff0c;我们需要了解几个基本概念&#xff1a;现在来分析源程序中的变量及其对应的十进制真值以及扩展操作方式&#xff1a; 1.1. short si -32768;1.2. unsigned short usi si;1.3. int i si;1.4. unsigned ui usi; 2&#x…

【开源】基于JAVA的农村物流配送系统

项目编号&#xff1a; S 024 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S024&#xff0c;文末获取源码。} 项目编号&#xff1a;S024&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2…

深度学习18

卷积层 查看每个数据 使用tensorboard查看 池化层 使用数据集进行训练 创建实例&#xff0c;使用tensorboard进行显示 最大池化保留了图片信息&#xff0c;神经网络训练的数据量大大减小&#xff0c;可以加快训练 非线性激活 非线性激活为神经网络加入了一些非线性的特质…

CTFSHOW sqll注入

号过滤绕过 号和不加通配符的 like 是一样的。 还可以使用 < >号来绕过&#xff0c;<> 在mysql中等于! 如果在加一个! 双重否定代表肯定 就是了 空格过滤绕过 /**/ &#xff0c;()&#xff0c;&#xff0c;tab&#xff0c;两个空格 or and xor not 过滤绕过 a…

正点原子linux应用编程——入门篇2

系统信息与系统资源 本章重点学习如何通过Linux系统调用或C库函数获取系统信息&#xff0c;譬如获取系统时间、日期 以及设置系统时间、日期等&#xff1b;除此之外&#xff0c;还会学习Linux系统下的/proc虚拟文件系统&#xff0c;包括/proc 文件系统是什么以及如何从/proc文…

【APUE】进程间通信

目录 一、管道 1.1 匿名管道 1.2 命名管道 二、XSI IPC 2.1 概述 2.2 消息队列 2.2.1 msgget 2.2.2 msgsnd 2.2.3 msgrcv 2.2.4 msgctl 2.2.5 代码示例 2.3 信号量数组 2.3.1 semget 2.3.2 semop 2.3.3 semctl 2.3.4 代码示例 2.3 共享内存 2.3.1 shmget…

selenium已知一个元素定位同级别的另一个元素

1.需求与实际情况 看下图来举例 &#xff08;1&#xff09;需求 想点击test22&#xff08;即序号-第9行&#xff09;这一行中右边的“复制”这一按钮 &#xff08;2&#xff09;实际情况 只能通过id或者class定位到文件名这一列的元素&#xff0c;而操作这一列的元素是不…

零基础可以学编程吗,不懂英语怎么学编程,中文编程工具实例

零基础可以学编程吗&#xff0c;不懂英语怎么学编程&#xff0c;中文编程工具实例 上图是中文编程工具界面、标尺实例。 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#x…

基于单片机体温心率脉搏检测仪系统设计

**单片机设计介绍&#xff0c; 基于单片机体温心率脉搏检测仪系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机体温心率脉搏检测仪是一种用于检测人体体温、心率和脉搏等基本生理指标的医疗设备。下面是一个简要…

QT 界面切换

先新建一个Widget工程 ui界面设置如下 在添加一个QT设计师界面类 右键点击添加 第二个UI界面设置如下 代码 链接&#xff1a;https://pan.baidu.com/s/1ovDIG2pno9mJ7mMFh2tq3Q 提取码&#xff1a;6q3m –来自百度网盘超级会员V2的分享

python+pytest接口自动化(2)-HTTP协议基础

HTTP协议简介 HTTP 即 HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09;&#xff0c;是互联网上应用最为广泛的一种网络协议。所有的 WWW 文件都必须遵守这个标准。 设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。HTTP 协议在 OSI 模型…

vue3 + element-plus + ts el-table封装

vue3 element-plus ts el-table封装 博客参考https://blog.csdn.net/weixin_45291937/article/details/125523244 1. 文件位置&#xff08;根据自己的需求&#xff09; 2. 在 custom 文件夹下面 创建 mytable 文件夹 3. 直接上代码 // index.vue<template><div …

Python实现WOA智能鲸鱼优化算法优化XGBoost回归模型(XGBRegressor算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 鲸鱼优化算法 (whale optimization algorithm,WOA)是 2016 年由澳大利亚格里菲斯大学的Mirjalili 等提…

CloudCompare简单开发

一、概述 CloudCompare如何进行二次开发&#xff1f;_cloudcompare 二次开发-CSDN博客 开发一个功能&#xff0c;在原始CC的基础上添加一个拓展功能&#xff0c;如下&#xff1a; 二、功能开发 1、修改MainWindow.UI 重点是&#xff1a;要编译&#xff0c;不然在mainwindow.…

JAVA进阶之路JVM-2:类加载机制,类的生命周期,类加载过程,类加载时机,类加载器,双亲委派模型,对象创建过程

JVM类加载机制 类加载 ​ 在JVM虚拟机实现规范中&#xff0c;通过ClassLoader类加载把*.class字节码文件&#xff08;文件流&#xff09;加载到内存&#xff0c;并对字节码文件内容进行验证&#xff0c;准备&#xff0c;解析和初始化&#xff0c;最终形成可以被虚拟机直接使用…

点盾云出现“操作失败,错误码1002”如何解决?

在使用点盾云学习看课时&#xff0c;老师会先将视频或者是在线播放链接发给我们&#xff0c;我们通过下载文件的方式或通过直接在线点播的形式来观看&#xff0c;那么在操作的过程中&#xff0c;有时候我们会遇到一些问题&#xff0c;今天以百度网盘中下载的视频文件为例&#…

浙江启用无人机巡山护林模式,火灾扑救效率高

为了保护天然的森林资源&#xff0c;浙江当地林业部门引入了一种创新技术&#xff1a;林业无人机。这些天空中的守护者正在重新定义森林防火和护林工作的方式。 当下正值天气干燥的季节&#xff0c;这些无人机开始了它们的首次大规模任务。它们在指定的林区内自主巡逻&#xff…

B树与B+树的对比

B树&#xff1a; m阶B树的核心特性&#xff1a; 树中每个节点至多有m棵子树&#xff0c;即至多含有m-1个关键字根节点的子树数属于[2, m]&#xff0c;关键字数属于[1, m-1]&#xff0c;其他节点的子树数属于 [ ⌈ m 2 ⌉ , m ] [\lceil \frac{m}{2}\rceil, m] [⌈2m​⌉,m]&am…