木舟0基础学习Java的第二十天(线程,实现,匿名有名,休眠,守护,加入,设计,计时器,通信)

多线程

并发执行的技术

并发和并行

并发:同一时间 有多个指令 在单个CPU上 交替执行

并行:同一时间 有多个指令 在多个CPU上 执行

进程和线程

进程:独立运行 任何进程 都可以同其他进程一起 并发执行

线程:是进程中的单个顺序控制流 是一条执行路径 线程又分为单线程和多线程

单线程:

多线程:JVM是多线程 其实就是JVM的主线程和垃圾回收线程在工作 结果在切换着运行

多线程的运行方式:他们拥有相等的运行权限 但运行过程是谁先抢到CPU的运行权限那么谁就先运行

线程的五种状态:新建,就绪,运行,堵塞,死亡

线程的实现:

方式一:继承Thread类

建立一个类继承Thread类 那么这类创建的对象可以并发的作为独立线程运行

继承的好处是可以使用父类中的方法 比较简单

继承的弊端是如果已经有父类了 就不可以再继承了 一个子类只能继承一个父类

public class Demo02 {public static void main(String[] args) {MyThread1 m1=new MyThread1();MyThread2 m2=new MyThread2();MyThread3 m3=new MyThread3();//普通方法/* m1.run();m2.run();m3.run();*///start开启新线程 内部会根据cpu的分配自动执行runm1.start();m2.start();m3.start();//相当于跑步比赛的发令枪 启动后主线程与其他线程都会等待抢到cpu的执行权//谁先抢到谁运行}
}
//建立一个类继承Thread类 那么这类创建的对象可以并发的作为独立线程运行
class MyThread1 extends Thread{public void run(){for (int i = 0; i <10000000 ; i++) {System.out.println("1号线程");}}
}
class MyThread2 extends Thread{public void run(){for (int i = 0; i <10000000 ; i++) {System.out.println("2号线程");}}
}
class MyThread3 extends Thread{public void run(){for (int i = 0; i <10000000 ; i++) {System.out.println("3号线程");}}
}

方式二:实现Runnable接口

建立一个类实现Runnable接口

接口的好处是就算实现了其他接口 也可以使用

接口的弊端 操作不便利 需要先获取Thread线程对象

public class Demo03 {public static void main(String[] args) {My1 my1=new My1();Thread t1=new Thread(my1);My2 my2=new My2();Thread t2=new Thread(my2);t1.start();t2.start();}
}
//定义一个类 实现Runnable接口 重新run方法class My1 implements Runnable{@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("1号线程");}}
}class My2 implements Runnable{@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("2号线程");}}
}

start()方法把当前线程交给了底层的  ThreadGroup group[]数组管理

Jvm根据随机分配的cpu执行权调用run()  随机分配的cpu执行权是相等概率的

匿名内部类实现线程

方式一:继承Thread类

 public static void main(String[] args) {new Thread(){public void run(){for(int i=0;i<10000000;i++){new Student();System.out.println("线程1");}}}.start();new Thread(){public void run(){for(int i=0;i<10000000;i++){new Student();System.out.println("线程2");}}}.start();}

方式二:实现Runnable接口

  public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("1号线程");}}}).start();new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("2号线程");}}}).start();}

有名内部类实现线程

 public static void main(String[] args) {Thread t1=new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("1号线程");}}});Thread t2=new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("2号线程");}}});t1.start();t2.start();}

设置名字和获取名字(getName() setName())

可以在运行中获取当前线程的对象Thread.currentThread()

public class Demo06 {public static void main(String[] args) {Thread t1=new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {//Thread.currentThread()获取当前运行的线程对象//获取名字getName()System.out.println(Thread.currentThread().getName());}}});Thread t2=new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println(Thread.currentThread().getName());}}});//设置名字t1.setName("线程1");t1.start();t2.setName("线程2");t2.start();}
}
通过构造方法给线程取名
public class Demo06 {public static void main(String[] args){//通过构造方法给线程取名Thread t1=new Thread(new M1(),"my1");Thread t2=new Thread(new M2(),"my2");t1.start();t2.start();}
}
class M1 implements Runnable{@Overridepublic void run() {for (int i = 0; i <100000 ; i++) {System.out.println(Thread.currentThread().getName());}}
}
class M2 implements Runnable{@Overridepublic void run() {for (int i = 0; i <100000 ; i++) {System.out.println(Thread.currentThread().getName());}}
}

休眠

Thread.sleep(100);让当前线程休眠100毫秒

class MM1 implements Runnable{@Overridepublic void run() {for (int i = 0; i <100000 ; i++) {System.out.println(Thread.currentThread().getName());try {//让当前线程休眠100毫秒Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}}}

守护线程

线程.setDaemon(true);

设置一个线程为守护线程 该线程不会单独执行 当其他非守护线程都执行结束后 再自动退出

public class Demo08 {public static void main(String[] args) {M2Thread m2=new M2Thread();m2.setName("线程2");m2.start();M1Thread m1=new M1Thread();m1.setName("线程1");m1.start();//守护线程不会单独执行Thread1 t=new Thread1();t.setName("守护线程");t.setDaemon(true);//设置true为守护线程 主线程结束 守护线程也结束t.start();}
}
class M1Thread extends Thread{public void run(){for (int i = 0; i <100 ; i++) {System.out.println(Thread.currentThread().getName());}}
}
class M2Thread extends Thread{public void run(){for (int i = 0; i <100 ; i++) {System.out.println(Thread.currentThread().getName());}}
}
class Thread1 extends Thread{public void run(){for (int i = 0; i <10000 ; i++) {System.out.println(Thread.currentThread().getName()+i);}}
}

加入线程

线程.join(可以限定时间 也可以不限定);

  public static void main(String[] args) {Thread t1=new Thread("女朋友的电话"){public void run(){for (int i = 0; i <100 ; i++) {System.out.println(Thread.currentThread().getName()+i);}}};Thread t2=new Thread("老板的电话"){public void run(){for (int i = 0; i <100 ; i++) {System.out.println(Thread.currentThread().getName()+i);if(i==50){try {//加入女朋友的线程 基本全面占有cpu执行权// t2线程要等待t1线程执行完毕后才可以继续执行t1.join();//可以限定时间} catch (InterruptedException e) {throw new RuntimeException(e);}}}}};t1.start();t2.start();}

礼让(了解)

Thread.yield();//让出cpu的执行权给别的线程

设置优先级:(优先级1-10 默认为5)

线程.setPriority(10);

同步(同步锁,同步代码块)

注意:开发中尽量不要嵌套同步代码块 可能会死锁
关键字:synchronized(同步锁使用的多)
public class Test {String s="123";//同步锁 在方法中加synchronized关键字//public synchronized void show1(){} public synchronized void show1(){System.out.print("我");System.out.print("爱");System.out.print("学");System.out.print("习");System.out.println("-----------");}public void show2(){//同步代码块synchronized(s锁对象){}//多个同步代码块如果使用相同的锁对象 那么他们就是同步的synchronized(s){ System.out.print("想");System.out.print("睡");System.out.print("觉");System.out.println("===========");}}
}

线程安全

synchronized线程安全  没有synchronized线程不安全

Vector线程安全  ArrayList线程不安全

Stringbuffer安全  stringBuilder不安全

HashTable安全  HashMap不安全

设计模式

单例设计模式

public class Single {private Single(){//私有构造方法 不让其他类new对象}static Single s=new Single();
}
    public static void main(String[] args) {Single s1=Single.s;Single s2=Single.s;System.out.println(s1==s2);//trueSingle s3=null;//对象可以被修改Single s4=Single.s;System.out.println(s3==s4);//false}
饿汉式(直接加载)

节约时间 浪费空间(例如:安卓手机应用可以在后台运行)

一旦被加载进来 就创建好了对象 不管是否使用 都在内存中
public class Single1 {private Single1(){//私有构造方法 不让其他类new对象}static Single1 s=new Single1();//饿汉式public static Single1 getInstance(){//一旦被加载进来 就创建好了对象 不管是否使用 都在内存中return s;}
}
public static void main(String[] args) {Single s1=Single.getInstance();Single s2=Single.getInstance();System.out.println(s1==s2);//true}
懒汉式(延迟加载)

节约空间 浪费时间(例如:苹果手机应用不挂后台)

什么时候用 什么时候才创建
public class Single2 {private Single2(){}public static Single2 s=null;//懒汉式public static Single2 Instance(){//需要的时候才创建对象if(s==null){s=new Single2();}return s;}
}

Runtime类单例(查API)

每个 Java 应用程序都有一个Runtime类实例 使应用程序能够与其运行的环境相连接 可以通过 getRuntime方法获取当前运行时。

应用程序不能创建自己的 Runtime类实例

 public static void main(String[] args) {Runtime r=Runtime.getRuntime();try {//r.exec("mspaint");//打开画图//r.exec("notepad");//打开记事本//r.exec("shutdown -s -t 6000");//6000秒后自动关机//r.exec("shurdown -a");//取消自动关机//r.exec("百度去");} catch (IOException e) {throw new RuntimeException(e);}}

Timer类(计时器)

用来定时执行程序的类
public class MyTask extends TimerTask {@Overridepublic void run() {System.out.println("起床了");}
}
 public static void main(String[] args) {//用来定时执行程序的类Timer t=new Timer();//5秒后执行任务t.schedule(new MyTask(),new Date(System.currentTimeMillis()+5000));//5秒后执行任务 每隔1秒重复执行t.schedule(new MyTask(),new Date(System.currentTimeMillis()+5000),1000);}

线程通信(等待,唤醒)

必须在同步代码块中 使用同步锁对象调用(唤醒 等待 唤醒 等待)代码交替运行

并发执行时 默认情况下 cpu的执行权 是随机的 谁先抢到谁先执行

如果希望有规律的执行 就可以用线程通信

notify唤醒 wait等待

案例:两个方法交替

public class TestThread2 {public synchronized void print(){System.out.print("我");System.out.print("爱");System.out.print("学");System.out.print("习");System.out.println("-----------");this.notify();//唤醒正在等待的线程try {this.wait();//让当前线程等待 让出cpu执行权 进入就绪状态} catch (InterruptedException e) {throw new RuntimeException(e);}}public synchronized void show(){System.out.print("想");System.out.print("睡");System.out.print("觉");System.out.println("===========");this.notify();//唤醒正在等待的线程try {this.wait();//让当前线程等待 让出cpu执行权 进入就绪状态} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
 public static void main(String[] args) {TestThread2 tt2=new TestThread2();new Thread(){public void run(){while(true){ tt2.print();}}}.start();new Thread(){public void run(){while(true){ tt2.show();}}}.start();}

案例:三个和三个以上方法交替

public class TestThread3 {boolean b1=true;boolean b2=false;boolean b3=false;public synchronized void show1() {if (b3) {System.out.print("我");System.out.print("爱");System.out.print("学");System.out.print("习");System.out.println("-----------");}b1 = true;b3 = false;this.notifyAll();//唤醒所有正在等待的线程try {this.wait();//让当前线程等待 让出cpu执行权 进入就绪状态} catch (InterruptedException e) {throw new RuntimeException(e);}}public synchronized void show2(){if(b1){System.out.print("想");System.out.print("睡");System.out.print("觉");System.out.println("===========");}b2=true;b1=false;this.notifyAll();//唤醒所有正在等待的线程try {this.wait();//让当前线程等待 让出cpu执行权 进入就绪状态} catch (InterruptedException e) {throw new RuntimeException(e);}}public synchronized void show3(){if(b2){System.out.print("想");System.out.print("吃");System.out.print("饭");System.out.println("~~~~~~~~~~~");}b2=false;b3=true;this.notifyAll();//唤醒所有正在等待的线程try {this.wait();//让当前线程等待 让出cpu执行权 进入就绪状态} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
 public static void main(String[] args) {TestThread3 tt3=new TestThread3();new Thread(){public void run(){while(true){tt3.show1();}}}.start();new Thread(){public void run(){while(true){tt3.show2();}}}.start();new Thread(){public void run(){while(true){tt3.show3();}}}.start();}

wait和sleep区别

wait():释放锁 等待并释放锁让别的线程运行

sleep():不释放锁 在指定的时间抱着锁睡 时间一到马上醒来

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

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

相关文章

【人工智能】深度剖析AI伦理:强化隐私防线,推动算法公平性的核心议题

文章目录 &#x1f34a;1 人工智能兴起背后的伦理及道德风险1.1 算法偏见与歧视1.2 数据隐私侵权1.3 透明度受限1.4 决策失衡1.5 AI生成内容的危险性 &#x1f34a;2 建构AIGC伦理观&#xff1a;实现人机共创的永续提升2.1 技术手段与伦理预防2.2 即时警告与紧急关停措施2.3 法…

图片如何去水印,PS 图片去水印的几种常见方法

在数字图像的世界里&#xff0c;水印常常被用来标识版权或防止未经授权的使用&#xff0c;但有时它们却成为了美观的障碍。无论是出于个人偏好还是专业需求&#xff0c;去除图片上的水印已经成为一项常见的任务。 Adobe Photoshop 作为行业标准的图像编辑软件&#xff0c;提供…

队列(Queue),循环队列,双端队列(Deque)and LeetCode刷题

队列&#xff08;Queue&#xff09;&#xff0c;循环队列&#xff0c;双端队列&#xff08;Deque&#xff09;and LeetCode刷题 1. 队列的概念2.队列的使用3. 队列的模拟实现3.1 用链式结构实现队列3.2 用顺序结构实现队列 4. 循环队列5. 双端队列&#xff08;Deque&#xff09…

【内网安全】横向移动-Wmi-Smb-CME密码喷射

目录 环境介绍域信息收集-横向移动前置判断是不是在域内获取域控主机的内网ip端口扫描内网获取主机密码 域横向移动-WMI-自带&命令&套件&插件1.wmic系统自带&#xff1a;(单执行&#xff1a;即无回显) 2.cscript系统自带&#xff1a;(交互式) 3.wmiexec-impacket&a…

文献阅读:A Case for Managed and Model-less Inference Serving

目录 知识点记录推理服务在线推理特点 动机&#xff1a;为什么作者想要解决这个问题&#xff1f;贡献&#xff1a;作者在这篇论文中完成了什么工作(创新点)&#xff1f;规划&#xff1a;他们如何完成工作&#xff1f;1.挑战1.1 选择一个模型变体1.2 异构硬件1.3 资源提供1.4 启…

MySQL双主双从实现方式

双主双从&#xff08;MM-SS&#xff09; 前言 避免单一主服务器宕机&#xff0c;集群写入能力缺失 从 1 复制 主1 &#xff0c;从 2 复制 主 2 主 1 复制 主 2&#xff0c;主 2 复制主 1 也就是 主 1 和主 2 互为主从。主1主2互为主从&#xff0c; 是为了以下情景&#xff0c…

初识XXE漏洞及ctfshow做题(373-378)

初识XXE漏洞 1.XXE简介 XXE就是XML外部实体注入&#xff0c;当允许引用外部实体时&#xff0c; XML数据在传输中有可能会被不法分子被修改&#xff0c;如果服务器执行被恶意插入的代码&#xff0c;就可以实现攻击的目的攻击者可以通过构造恶意内容&#xff0c;就可能导致任意…

昇思25天学习打卡营第29天 | 文本解码原理--以MindNLP为例

今天是29天&#xff0c;学习了文本解码原理--以MindNLP为例。 MindNLP 是一个基于 MindSpore 的开源自然语言处理&#xff08;NLP&#xff09;库。它具有以下特点&#xff1a; 支持多种 NLP 任务&#xff1a;如语言模型、机器翻译、问答、情感分析、序列标记、摘要等&#xff…

SPINDILOMETER:用于多导睡眠图的睡眠纺锤波模型

摘要 通过对近年来睡眠脑电(EEG)信号分析方法的研究&#xff0c;本文提出了一种可集成到多导睡眠图(PSG)设备中的SPINDILOMETER模型&#xff0c;以供PSG电生理信号研究人员、临床睡眠医生和技术人员使用。为此&#xff0c;通过分析PSG中的脑电信号&#xff0c;开发了一个测量睡…

算法题目整合

文章目录 121. 小红的区间翻转142. 两个字符串的最小 ASCII 删除总和143. 最长同值路径139.完美数140. 可爱串141. 好二叉树 121. 小红的区间翻转 小红拿到了两个长度为 n 的数组 a 和 b&#xff0c;她仅可以执行一次以下翻转操作&#xff1a;选择a数组中的一个区间[i, j]&…

【Neural signal processing and analysis zero to hero】- 2

Nonstationarities and effects of the FT course from youtube: 传送地址 why we need extinguish stationary and non-stationary signal, because most of neural signal is non-stationary. Welch’s method for smooth spectral decomposition Full FFT method y…

用Docker来开发

未完成。。。 现在好像用Docker是越来越多了。之前其实也看过docker的原理&#xff0c;大概就是cgroup那些&#xff0c;不过现在就不看原理了&#xff0c;不谈理论&#xff0c;只看实际中怎么用&#xff0c;解决眼前问题。 用docker来做开发&#xff0c;其实就是解决的编译环境…

ArkUI-动画

属性动画 属性动画是通过设置组建的animation属性来给组件添加动画&#xff0c;当组件的width、height、Opacity、backgroundColor、scale、rotate、translate等属性变更时&#xff0c;可以实现渐变过渡效果 Text().position({x: 10, //x轴坐标y: 0 //y轴坐标}).rotate…

在 PostgreSQL 里如何处理数据的存储优化和查询优化的优先级权衡?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 里如何处理数据的存储优化和查询优化的优先级权衡一、存储优化与查询优化的概述&#x…

阿里:深入探讨Java的分层编译

本文主要探讨Java虚拟机&#xff08;JVM&#xff09;中的分层编译&#xff08;Tiered Compilation&#xff09;机制及其对程序性能的影响。 前言 一开始接触到分层编译是因为我们这的服务每次发布/重启后都会短暂地出现CPU满线程池满的情况&#xff0c;然后过一段时间又能自动…

学习008-01-03 Customize the Application UI and Behavior(自定义应用程序UI和行为)

Customize the Application UI and Behavior&#xff08;自定义应用程序UI和行为&#xff09; In XAF, the data model defines the database structure and UI. Changes to your entity classes affect the UI. For example, if you add a new property to an entity class, …

C++ | Leetcode C++题解之第239题滑动窗口最大值

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int n nums.size();vector<int> prefixMax(n), suffixMax(n);for (int i 0; i < n; i) {if (i % k 0) {prefixMax[i] num…

MySQL(7)内外连接+索引

目录 1.内外连接; 2. 索引; 1.内外连接: 1.1内连接: 语法: select 字段 from 表名 inner join 表名 on 字段限制; 1.2 外连接: 分为左右外连接; (1)左外连接: 语法: select * from 表名 left join 表名 on 字段限制. &#x1f330;查询所有学生的成绩&#xff0c;如果这个学生…

MySQL(8)事务

目录 1.事务; 1.事务: 1.1 如果CURD不加限制会这么样子? 可能造成数据同时被修改, 数据修改的结果是未知的.(可以想一下之前的抢票线程问题) 1.2 事务概念: 事务就是一组DML语句组成&#xff0c;这些语句在逻辑上存在相关性&#xff0c;这一组DML语句要么全部成功&#xff0…

【Python实战因果推断】40_双重差分11

目录 Heterogeneous Effect over Time Heterogeneous Effect over Time 有好消息也有坏消息。首先是好消息&#xff1a;你已经发现了问题所在。也就是说&#xff0c;你知道 TWFE 在应用于具有时间异构效应的交错采用数据时是有偏差的。用更专业的术语来说&#xff0c;您的数据…