java 多线程 上

news2024/11/22 22:21:50

目录

基本概念

线程的创建和使用

Thread类

API中创建线程的两种方式

Thread类的有关方法

线程的调度

线程的优先级

总结 


基本概念

程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。

进程(process)是程序的一次执行过程,或是正在运行的一个程序。是一个动态的过程:有它自身的产生、存在和消亡的过程。——生命周期

  • 如:运行中的QQ,运行中的MP3播放器
  • 程序是静态的,进程是动态的
  • 进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域

线程(thread),进程可进一步细化为线程,是一个程序内部的一条执行路径。

  • 若一个进程同一时间并行执行多个线程,就是支持多线程的
  • 线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc),线程切换的开销小
  • 一个进程中的多个线程共享相同的内存单元/内存地址空间它们从同一堆中分配对象,可以 访问相同的变量和对象。这就使得线程间通信更简便、高效。但多个线程操作共享的系统资 源可能就会带来安全的隐患

 

单核CPU和多核CPU的理解

单核CPU,其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程的任务。例如:虽然有多车道,但是收费站只有一个工作人员在收费,只有收了费才能通过,那么CPU就好比收费人员。如果有某个人不想交钱,那么收费人员可以把他“挂起”(晾着他,等他想通了,准备好了钱,再去收费)。但是因为CPU时间单元特别短,因此感觉不出来。

  • 如果是多核的话,才能更好的发挥多线程的效率。(现在的服务器都是多核的)
  • 一个Java应用程序java.exe,其实至少有三个线程:main()主线程,gc()垃圾回收线程,异常处理线程。当然如果发生异常,会影响主线程。

 并行与并发

  • 并行:多个CPU同时执行多个任务。比如:多个人同时做不同的事。
  • 并发:一个CPU(采用时间片)同时执行多个任务。比如:秒杀、多个人做同一件事。

使用多线程的优点

背景:以单核CPU为例,只使用单个线程先后完成多个任务(调用多个方 法),肯定比用多个线程来完成用的时间更短,为何仍需多线程呢?

多线程程序的优点:

  • 1. 提高应用程序的响应。对图形化界面更有意义,可增强用户体验。
  • 2. 提高计算机系统CPU的利用率
  • 3. 改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改

何时需要多线程

  • 程序需要同时执行两个或多个任务。
  • 程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
  • 需要一些后台运行的程序时

线程的创建和使用

Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread 类来体现。

Thread类的特性

  • 每个线程都是通过某个特定Thread对象的run()方法来完成操作的,经常 把run()方法的主体称为线程体
  • 通过该Thread对象的start()方法来启动这个线程,而非直接调用run()

Thread

构造器
  • Thread()创建新的Thread对象
  • Thread(String threadname)创建线程并指定线程实例名
  • Thread(Runnable target)指定创建线程的目标对象,它实现了Runnable接口中的run方法
  • Thread(Runnable target, String name)创建新的Thread对象

API中创建线程的两种方式

JDK1.5之前创建新执行线程有两种方法:

  • 继承Thread类的方式
  • 实现Runnable接口的方式

方式一:继承Thread

  • 1) 定义子类继承Thread类。
  • 2) 子类中重写Thread类中的run方法。
  • 3) 创建Thread子类对象,即创建了线程对象。
  • 4) 调用线程对象start方法:启动线程,调用run方法。

 注意点:

  • 1.. 如果自己手动调用run()方法,那么就只是普通方法,没有启动多线程模式。
  • 2. run()方法由JVM调用,什么时候调用,执行的过程控制都有操作系统的CPU调度决定。
  • 3. 想要启动多线程,必须调用start方法。
  • 4. 一个线程对象只能调用一次start()方法启动,如果重复调用了,则将抛出以上的异常“IllegalThreadStateException

方式二:实现Runnable接口

  • 1) 定义子类,实现Runnable接口。
  • 2) 子类中重写Runnable接口中的run方法。
  • 3) 通过Thread类含参构造器创建线程对象。
  • 4) Runnable接口的子类对象作为实际参数传递给Thread类的构造器中。
  • 5) 调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法。

继承方式和实现方式的联系与区别

public class Thread extends Object implements Runnable

区别

  • 继承Thread:线程代码存放Thread子类run方法中。
  • 实现Runnable:线程代码存在接口的子类的run方法。

实现方式的好处

  • 避免了单继承的局限性
  • 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。

Thread类的有关方法

  • void start(): 启动线程,并执行对象的run()方法
  • run(): 线程在被调度时执行的操作
  • String getName(): 返回线程的名称
  • void setName(String name):设置该线程名称
  • static Thread currentThread(): 返回当前线程。在Thread子类中就this,通常用于主线程和Runnable实现类
  • static void yield()线程让步,暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程 若队列中没有同优先级的线程,忽略此方法
  • join() 当某个程序执行流中调用其他线程的 join() 方法时,调用线程将被阻塞,直到 join() 方法加入的 join 线程执行完为止 ,低优先级的线程也可以获得执行
  • static void sleep(long millis)(指定时间:毫秒) 令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。抛出InterruptedException异常
  • stop(): 强制线程生命期结束,不推荐使用
  • boolean isAlive()返回boolean,判断线程是否还活着

线程的调度

 

 

ava 的调度方法
  • 同优先级线程组成先进先出队列(先到先服务),使用时间片策略
  • 对高优先级,使用优先调度的抢占式策略

线程的优先级

线程的优先级等级

  • MAX_PRIORITY10
  • MIN _PRIORITY1
  • NORM_PRIORITY5

涉及的方法

  • getPriority() 返回线程优先值
  • setPriority(int newPriority) 改变线程的优先级

说明

  • 线程创建时继承父线程的优先级
  • 低优先级只是获得调度的概率低,并非一定是在高优先级线程之后才被调用

总结 

Java中的线程分为两类:一种是守护线程,一种是用户线程

  • 它们在几乎每个方面都是相同的,唯一的区别是判断JVM何时离开。
  • 守护线程是用来服务用户线程的,通过在start()方法前
  • 调用thread.setDaemon(true)可以把一个用户线程变成一个守护线程。
  • Java垃圾回收就是一个典型的守护线程。
  • JVM中都是守护线程,当前JVM将退出。
package com.jyc.p1;

/*
多线程的创建 方式-,继承于Thread类
 1.创建一个继承于 Thread 类的子类
 2.重写thread类的run()方法---> 将此线程执行的操作声明在run中
 3.创建thread类的子类对象
 4.通过对象调用start()

Thread中的常用方法
1.start()启动当前线程,调用当前线程的run方法
2.run() 通常需要重写 Thread 类中的此方法,将创建的线程要执行的操作声明在此方法中
3.currentThread()静态方法:返回执行当前代码的线程
4.getName()获取当前线程的名字
5.setName()设置当前线程的名字 (也可以使用构造器)
6..join() 在线程a中调用线程b的join()此时线程a就进入了阻塞状态,直到线程b完全执行完以后,线程a
        才结束阻塞状态
7.yield() 释放当前cpu执行权
8.stop() 已过时,当执行此方法时,强制结束当前线程
9. sleep(lang millitime) 让当前线程睡眠指定的是毫秒,在指定的时间内线程是阻塞状态
10. isAlive 判断当前线程是否还存活


线程的优先级等级
    MAX_PRIORITY:10
    MIN _PRIORITY:1
    NORM_PRIORITY:5---> 默认优先级
    getPriority获取线程的优先级
    setPriority(int p)设置线程优先级
    说明:高优先级的线程抢占低优先级的线程cpu执行权,但是只是从概率上将,高优先级的线程高概率的情况下被
执行,并不意味着只有当高优先级的线程执行完以后,低优先级的线程才执行


创建多线程的方式二
1.创建一个实现了 Runnable 接口的类
2.实现类去实现 Runnable中的抽象方法
3.创建实现类的对象
4.将此对象作为参数传递到 Thread 类的构造器中 创建 Thread 类的对象
5. 通过 Thread 类的对象 调用 start方法


比较创建线程的两种方式
开发中优先选择实现Runnable接口的方式
原因:
实现的方式吗,没右类的单继承性的局限性
实现的方式更适合来处理多个线程共享数据的情况
相同点两种方式都需要重写run将线程要执行的逻辑声明在run中



*
* */
class  MyThread1 implements Runnable{
    @Override
    public void run() {

        for(int i=0;i<100;i++){
            if(i%2==0){
               System.out.println(i);
            }
        }
    }
}
class MyThread extends Thread{
    @Override
    public void run() {
        for (int i=0;i<100;i++){
            if(i%2==0){
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() +i);

            }
            System.out.println( isAlive());
            System.out.println(Thread.currentThread().getPriority());
        }
    }
}
public class ThreadTest {
    public static void main(String[] args) {
        MyThread1  myThread1=new   MyThread1();
        Thread t2=new Thread(myThread1);
        t2.start();
        MyThread t1=new MyThread();
        /*
        * 通过对象调用start()1.启动当前线程,2.调用当前线程的run方法
        *   我们不能通过直接调用run的方式启动线程
        *   不可以让已经start的线程去执行(需要重新创建一个线程对象)
        * */
        t1.setName("线程一");
        t1.start();
        //如下操作仍是main线程中执行的
        System.out.println("hello");

        for (int i=0;i<100;i++){
            if(i%2==0){
                System.out.println(Thread.currentThread().getName() +i);

            }
            if (i==20){
             try{
                 t1.join();
             }catch ( InterruptedException e){
                e.printStackTrace();
             }

            }
            System.out.println(Thread.currentThread().getPriority());

    }

}}

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

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

相关文章

TapTap 算法平台的 Serverless 探索之路

作者&#xff1a;陈欣昊 Serverless 在构建应用上为 TapTap 节省了大量的运维与开发人力&#xff0c;在基本没投入基建人力的情况下&#xff0c;直接把我们非常原始的基建&#xff0c;或者说是资源管理水平拉到了业界相对前沿的标准。最直观的数据是&#xff0c;仅投入了个位数…

代码随想录Day55|392.判断子序列、115.不同的子序列

文章目录392.判断子序列115.不同的子序列392.判断子序列 文章讲解&#xff1a;代码随想录 (programmercarl.com) 题目链接&#xff1a;392. 判断子序列 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。…

koa 使用

&#xff08;贴个官网&#xff0c;koa 内容真不多&#xff0c;非常的小巧轻量&#xff09; 1. koa 是什么 一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用&#xff0c;通过组合不同的 generator&#xff0c;可以免除重复繁琐的回调函数嵌套&#xff0c;…

关于新正方教务系统(湖北工程学院)的one day越权漏洞的说明

关于正方教务系统漏洞的说明 此漏洞基于湖北工程学院教务管理系统进行演示&#xff0c;漏洞覆盖新正方教务系统8.0以下版本&#xff0c;为本人一年前提交的漏洞&#xff0c;所以并非0day漏洞 此漏洞影响范围巨大&#xff0c;几乎涉及国内一半高校的教务系统&#xff0c;包含武…

我国油气行业勘探开发投入提升 石油资源存在供需短缺矛盾 天然气需求高速发展

根据观研报告网发布的《2022年中国油气市场分析报告-市场竞争策略与发展动向前瞻》显示&#xff0c;油气是指石油和伴生的天然气&#xff0c;被誉为“能源之王”、“工业的血液”&#xff0c;是全世界各国的战略性产业。油气资源种类多样&#xff0c;根据开采难度可分为两大类&…

Python:三方库安装路径及路径变更

文章目录一、安装三方库的几种方式二、指定第三方库的镜像源三、查看安装默认路径四、修改安装默认路径五、查看安装的库六、导出库安装文件七、安装小结一、安装三方库的几种方式 1.直接pip install安装&#xff08;有网的环境下通用&#xff09; &#xff1a; 在python–>…

CSDN上讲得最好的——Linux权限

目录 一、shell原理精讲 二、Linux权限概念 三、权限管理 1、访问者分类 2、文件类型及访问权限 3、表示方法 4、设置方法 &#xff08;1&#xff09;chmod (2)chown (3)chgrp (4)umask 四、目录权限 五、粘滞位 一、超级管理员删除 二、该目录的所有者删除 三、…

GDAL之重投影(详细篇)

一、空间坐标系对应EPSG编号 二、通用横向墨卡托(UTM)投影坐标系和WGS84地理坐标系转换 一、目标地区的编号查看(中国东部地区属于UTM Zone 50N) 从180“W开始&#xff0c;有60个纵向投影区&#xff0c;编号为1到60。除了挪威和斯瓦尔巴群岛附近的一些例外&#xff0c;每个区…

【毕业设计_课程设计】基于 U-Net 网络的遥感图像语义分割(源码+论文)

文章目录0 项目说明1 研究目的2 研究方法3 研究结论4 论文目录5 项目工程0 项目说明 **基于 U-Net 网络的遥感图像语义分割 ** 提示&#xff1a;适合用于课程设计或毕业设计&#xff0c;工作量达标&#xff0c;源码开放 实验训练使用 Anaconda 版 Python 3.7 下的 TensorFlo…

OpenSSL BIO源码简析

文章目录1. BIO简介BIO chainBIO数据结构BIO_METHOD数据结构2. Base64示例分析初始化构造BIO链写数据free1. BIO简介 相关文档 /html/man7/bio.html /html/man3/BIO_*.htmlbio - Basic I/O abstraction&#xff0c;即IO抽象层。 BIO有两种: source/sink BIO&#xff0c;即数…

win7系统升级IE11,打补丁KB2729094失败解决办法

因银行这边很多都需要IE11版本&#xff0c;但win7系统大部分需要打一些补丁才能安装。其他补丁都打上了&#xff0c;唯独这个KB2729094一直失败&#xff0c;搞得很无语。还好找到可以直接用命令安装。就不需要打这个补丁了&#xff0c;直接安装使用即可。 1、下载IE11离线安装…

DBCO-PEG-Dopamine,二苯并环辛炔-聚乙二醇-多巴胺,DBCO聚乙二醇衍生物

●中文名&#xff1a;二苯并环辛炔-聚乙二醇-多巴胺&#xff0c;多巴胺聚乙二醇环辛炔 ●英文名&#xff1a;DBCO-PEG-Dopamine&#xff0c;Dopamine-PEG-DBCO ●外观以及性质&#xff1a; DBCO-PEG-Dopamine产物呈固体或粘性液体&#xff0c;取决于PEG分子量&#xff0c;DBCO…

“R语言+遥感”的水环境综合评价方法

目标&#xff1a; 1、掌握R语言基础应用及水环境数据分析方法 2、掌握水环境遥感数据预处理方法 3、掌握水线提取——水体指数与阈值混合法&#xff08;遥感&#xff09; 4、掌握水深提取——多元回归分析方法&#xff08;R语言遥感&#xff09; 5、掌握水温提取——支持向…

(附源码)springboot学生社团信息管理 毕业设计 011238

目 录 摘要 1 1 绪论 1 1.1 研究背景 1 1.2 研究意义 1 1.3论文结构与章节安排 1 2 学生社团信息管理系统系统分析 3 2.1 可行性分析 3 2.2 系统流程分析 3 2.2.1 数据增加流程 4 2.2.2 数据修改流程 4 2.2.3 数据删除流程 5 2.3 系统功能分析 5 2.3.1 功能性分析 5 2.3.2 非功…

D. Secret Santa(构造)

Problem - 1530D - Codeforces 每年12月&#xff0c;VK都会为其员工举办名为 "秘密圣诞老人 "的传统活动。它是这样发生的。 从1到n的n名员工参加了这个活动。每个员工i被分配到一个不同的员工bi&#xff0c;员工i必须给这个员工做一份新年礼物。每个员工正好被分配…

如何使用Chrome浏览器模拟弱网情况

点击谷歌浏览器图标 打开浏览器后&#xff0c;按下F12键 弹出开发者工具窗口 刷新网页&#xff0c;页面的加载速度为597ms 在开发者工具中&#xff0c;点击Online&#xff0c;在弹出的菜单中点击Slow 3G&#xff08;慢速3G网络&#xff09; 重新加载网站&#xff0c;…

PyTorch logit函数

1.PyTorch vs TensorFlow tensorflow是静态图&#xff0c;需要你把啥都准备好&#xff0c;然后它像个傻子一样执行&#xff0c;tensorflow&#xff0c;目前业界更适合部署&#xff0c;毕竟是静态图&#xff0c;infer的时候速度快。 pytorch&#xff0c;它会在执行的时候&…

Android -- 每日一问:如何检测内存泄露,如何进行内存优化?

经典回答 Android 系统为每一个应用程序都设置了一个硬性的 Dalvik Heap Size 最大限制阈值&#xff0c;这个阈值在不同的设备上会因为 RAM 大小不同而各有差异。如果你的应用占用内存空间已经接近这个阈值&#xff0c;此时再尝试分配内存的话&#xff0c;很容易引起 OOM 。 …

效果分析的关键是指标能算出来……

看到题目会不会有一些奇怪&#xff1f; 这算什么关键…… 经历过才知道&#xff0c;这是一个不起眼但却极为重要的部分&#xff0c;企业在数据驱动发展进程中必然会遇到指标算不出来的情况&#xff0c;而且随着企业规模的不断扩大&#xff0c;这一问题会持续伴随。“指标能算…

[附源码]Python计算机毕业设计Django学习互助辅助系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…