位置: IT常识 - 正文

Java学习-第一部分-第二阶段-第七节:泛型(java第一步)

编辑:rootadmin
线程 笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 程序(program) 是为完成特定任务、用某种语言编写的一组指令的集合。简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会 ... 线程

推荐整理分享Java学习-第一部分-第二阶段-第七节:泛型(java第一步),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:学java第一步要做什么,java第一课,java第一课,java第一步学什么,java编程第一步,java第一阶段要学的知识,java第一步学什么,java第一课,内容如对您有帮助,希望把文章链接给更多的朋友!

笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html)

程序(program)

是为完成特定任务、用某种语言编写的一组指令的集合。简单的说:就是我们写的代码

进程

进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间。当我们使用迅雷,又启动了一个进程,操作系统将为迅雷分配新的内存空间。进程是程序的一次执行过程,或是正在运行的一个程序。是动态过程:有它自身的产生、存在和消亡的过程线程介绍

什么是线程

线程由进程创建的,是进程的一个实体2.一个进程可以拥有多个线程(例如迅雷中 多个下载任务同时进行)

坦克大战(每个敌人坦克就是一个线程)[后面会把多线程加入到坦克大战中,学以致用]

其他相关概念

单线程:同一个时刻,只允许执行一个线程

多线程:同一个时刻,可以执行多个线程,比如:一个qq进程,可以同时打开多个聊天窗口,一个迅雷进程,可以同时下载多个文件

并发:同一个时刻,多个任务交替执行,造成一种“貌似同时”的错觉,简单的说,单核cpu实现的多任务就是并发。

并行:同一个时刻,多个任务同时执行。多核cpu可以实现并行。

public class Test { public static void main(String[] args) { Runtime runtime = Runtime.getRuntime(); //获取当前电脑的cpu数量/核心数 int cpuNums = runtime.availableProcessors(); System.out.println("当前有CPU个数"+cpuNums); }}线程使用

创建线程的两种方式

在java中线程来使用有两种方法。

继承Thread类,重写run方法

实现Runnable接口,重写run方法

继承Thread

线程应用案例1-继承Thread类

请编写程序,开启一个线程,该线程每隔1秒。在控制台输出“啪瞄,我是小猫咪'

对上题改进:当输出80次唶瞄,我是小猫咪,结束该线程

使用JConsole监控线程执行情况,并画出程序示意图!

public class Test { public static void main(String[] args) throws InterruptedException { //创建Cat对象,可以当做线程使用 Cat cat = new Cat(); /* (1) public synchronized void start() { start0(); } (2) //start0()是本地方法,是JVM调用,底层是c/c++实现 //真正实现多线程的效果,是start0(),而不是 run private native void start0(); */ cat.start();//启动线程 //cat.run();//run方法就是一个普通的方法,没有真正的启动一个线程,就会把run方法执行完毕,才向下执行 //说明:当main线程启动一个子线程 Thread-0,主线程不会阻塞,会继续执行//这时主线程和子线程是交替执行.. System.out.println("主线程继续执行" + " 线程名" + Thread.currentThread().getName());//线程main for (int i = 0; i < 60; i++) { System.out.println("主线程i=" + i); //让主线程休眠 Thread.sleep(1000); } }}//说明//1。当一个类继承了 Thread 类,该类就可以当做线程使用//2.我们会重写 run方法,写上自己的业务代码//3.run Thread类实现了Runnable接口的run方法/* @Override public void run() { if (target != null) { target.run(); } }*/class Cat extends Thread { int times = 0; @Override public void run() { while (true) { //该线程每隔1秒。在控制台输出“瞄瞄,我是小猫咪" System.out.println("瞄瞄,我是小猫咪" + " 线程名" + (++times) + Thread.currentThread().getName());//让该线程休眠1秒ctrl+alt+t try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (times == 80) { break; //当times 到80,退出while,这时线程也就退出.. } } }}

start()方法原理

实现RunnableJava学习-第一部分-第二阶段-第七节:泛型(java第一步)

线程应用案例2-实现Runnable接口

说明

java是单继承的,在某些情况下一个类可能已经继承了某个父类,这时在用继承Thread类方法来创建线程显然不可能了。java设计者们提供了另外一个方式创建线程,就是通过实现Runnable接口来创建线程

线程使用应用案例-实现Runnable接口

应用案例

请编写程序该程序可以每隔1秒。在控制台输出“hi!”,当输出10次后,自动退出。请使用实现Runnable接口的方式实现。

public class Test { public static void main(String[] args) throws InterruptedException { Dog dog = new Dog(); //dog.start();这里不能调用start //创建了Thread对象,把 dog对象(实现Runnable),放入Thread Thread thread = new Thread(dog); thread.start(); }}class Dog implements Runnable {//通过实现Runnable接口,开发线程 int count = 0; @Override public void run() {//普通方法 while (true) { System.out.println("小狗汪汪叫..hi" + (++count) + Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (count>10){ break; } } }}

这里底层使用了设计模式【代理模式】

以下为代码模拟 实现Runnable接口开发线程的机制(可以用来代替上述代码中的Thread类的功能)此处只是模拟来展示原理,并不能实际创建新线程,任然是执行main线程

//线程代理类,模拟了一个极简的Thread类class ThreadProxy implements Runnable {//你可以把Proxy类当做 ThreadProxy private Runnable target = null;//属性,类型是 Runnable @Override public void run() { if (target != null) { target.run(); } } public ThreadProxy(Runnable target) { this.target = target; } public void start() { start0(); } public void start0() { run(); }}

继承Thread vs 实现Ruunnable的区别

从java的设计来看,通过继承Thread或者实现Runnable接口来创建线程本质上没有区别,从jdk帮助文档我们可以看到Thread类本身就实现了Runnable接口实现Runnable接口方式更加适合多个线程共享一个资源的情况,并且避免了单继承的限制(建议使用Runnnable接口)

思考:[售票系统],编程模拟三个售票窗口售票100张,分别使用继承 Thread和实现Runnable方式,并分析有什么问题?

public class Test { public static void main(String[] args) {//测试 SellTicket01 sellTicket01 = new SellTicket01(); SellTicket01 sellTicket02 = new SellTicket01(); SellTicket01 sellTicket03 = new SellTicket01(); //这里会出现超卖问题 sellTicket01.start();//启动售票线程 sellTicket02.start();//启动售票线程 sellTicket03.start();//启动售票线程 }}class SellTicket01 extends Thread { private static int ticketNum = 100;//让多个线程共享ticketNum @Override public void run() { while (true) { if (ticketNum <= 0) { System.out.println("售票结束..."); break; } //休眠50毫秒 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("窗口" + Thread.currentThread().getName() +"售出一张票" + "剩余票数=" + (--ticketNum)); } }}线程终止

基本说明

当线程完成任务后,会自动退出。还可以通过使用变量来控制run方法退出的方式停止线程,即通知方式

●应用案例

需求:启动一个线程,要求在main线程中去停止线程t,请编程实现.

public class Test { public static void main(String[] args) throws InterruptedException { T t1 = new T(); Thread thread = new Thread(t1); thread.start(); //如果希望main线程去控制t1 线程的终止,必须可以修改 loop // 让t1退出run方法,从而终止t1线程->通知方式 //让主线程休眠10秒,再通知t1线程退出 System.out.println("main线程休眠10s"); Thread.sleep(5 * 1000); t1.setLoop(false); }}class T implements Runnable { boolean loop = true;//步骤1:定义标记变量,默认为true@Override int count=0; @Override public void run() { while (loop) {//步骤2:将loop作为循环条件 try { Thread.sleep(50);//让当前线程休眠10ms } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("AThread运行中...."+(++count)); } } //步骤3:提供公共的set方法,用于更新loop public void setLoop(boolean loop) { this.loop = loop; }}线程常用方法常用方法第一组setName //设置线程名称,,使之与参数name相同getName //返回该线程的名称start //使该线程开始执行;Java虚拟机底层调用该线程的start0方法run //调用线程对象 run方法;setPriprity //更改线程的优先级getPriority //获取线程的优先级sleep //在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)interrupt //中断线程

注意事项和细节

start底层会创建新的线程,调用run。run 就是一个简单的方法调用,本身不会启动新线程

线程优先级的范围

sleep:线程的静态方法,使当前线程休眠

interrupt:中断线程,但并没有真正的结束线程。所以一般用于中断正在休眠线程

public class Test { public static void main(String[] args) throws InterruptedException { //测试相关的方法 T t = new T(); t.setName("老韩"); t.setPriority(Thread.MIN_PRIORITY);//1 t.start();//启动子线程 //主线程打印5hi,然后我就中断子线程的休眠 for (int i = 0; i < 5; i++) { Thread.sleep(1000); System.out.println("hi " + i); } t.interrupt();//当执行到这里,就会中断t线程的休眠。 }}class T extends Thread { int count=0; @Override public void run() { while (true) { for (int i = 0; i < 100; i++) { //Thread.currentThread().getName()获取当前线程的名称 System.out.println(Thread.currentThread().getName() + "吃包子~" + i); } try { System.out.println(Thread.currentThread().getName() + "休眠中 ~~~"+(++count)); Thread.sleep(20000);//20秒 } catch (InterruptedException e) { //当该线程执行到一个interrupt 方法时,就会catch一个异常,可以加入自己的业务代码 //InterruptedException是捕获到一个中断异常。 System.out.println(Thread.currentThread().getName() + "被interrupt了"); } } }}常用方法第二组

yield:线程的礼让。让出cpu,让其他线程执行,但礼让的时间不确定,所以也不一定礼让成功(例:Thread.yield();//礼让自己使用cpu资源,不指定某一特定线程。具体用法看下面代码)

join:线程的插队。插队的线程一旦插队成功,则肯定先执行完插入的线程所有的任务(例:t2.join();//指定特定的某一线程先完成任务,再执行自己的工作)

案例:创建一个子线程,每隔1s输出hello,输出20次,主线程每隔1秒,,输出hi,输出20次.要求:两个线程同时执行,当主线程输出5次后,就让子线程运行完毕,主线程再继续

public class Test { public static void main(String[] args) throws InterruptedException { T2 t2 = new T2(); t2.start(); for (int i = 1; i <= 20; i++) { Thread.sleep(1000); System.out.println("主线程(小弟)吃了" +i+"个包子"); if (i == 5) { System.out.println("主线程(小弟)让子线程(老大)先吃"); //join,线程插队 //t2.join();// 这里相当于让t2 线程先执行完毕 Thread.yield();//礼让,不一定成功 System.out.println("线程(老大)吃完了主线程(小弟)接着吃.."); } } }}class T2 extends Thread { public void run() { for (int i = 1; i <= 20; i++) { try { Thread.sleep(1000);//休眠1秒 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("子线程(老大)吃了" + i + "包子"); } }}

用户线程和守护线程

用户线程:也叫工作线程,当线程的任务执行完或通知方式结束守护线星:一般是为工作线程服务的,当所有的用户线程结束,守护线程自动结束常见的守护线程:垃圾回收机制public class Test { public static void main(String[] args) throws InterruptedException { MyDaemonThread myDaemonThread = new MyDaemonThread(); //如果我们希望当main线程结束后,子线程自动结束 //,只需将子线程设为守护线程即可 myDaemonThread.setDaemon(true);//守护线程要在该线程启动前设置 myDaemonThread.start(); for (int i = 1; i <= 10; i++) {//main线程 System.out.println("宝强在辛苦的工作..."); Thread.sleep(1000); } }}class MyDaemonThread extends Thread { public void run() { while (true) {//无限循环 try { Thread.sleep(1000);//休眠1000毫秒 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("马蓉和宋喆快乐聊天,哈哈哈~~~"); } }}线程的生命周期

JDK文档中用Thread.State枚举表示了线程的几种状态

线程状态转换图

synchronized

线程同步机制

在多线程编程,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何同一时刻,最多有一个线程访问,以保证数据的完整性。也可以这里理解:线程同步,即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内仔地址进行操作.

同步具体方法-Synchronized

注意 synchronized锁的是一个特定的对象。而不是方法,也不是某块代码(由同一类创建的不同对象中的同一方法或代码并不能被synchronized锁)

同步代码块

synchronized(对象){//得到对象的锁,才能操作同步代码 //需要被同步代码;}

synchronized还可以放在方法

本文链接地址:https://www.jiuchutong.com/zhishi/311635.html 转载请保留说明!

上一篇:三个数排序(三个数排序c语言程序从大到小)

下一篇:织梦自定义表单时间类型字段显示为数字的解决办法(织梦自定义表单diy.php更改名字)

  • 怎样做好分类信息网站推广(如何做好分类)

    怎样做好分类信息网站推广(如何做好分类)

  • 荣耀magic3怎么截屏(荣耀x50怎么截屏)

    荣耀magic3怎么截屏(荣耀x50怎么截屏)

  • vivoiQOO锁屏原子随身听怎么关闭(vivo手机怎么关闭原子桌面)

    vivoiQOO锁屏原子随身听怎么关闭(vivo手机怎么关闭原子桌面)

  • 钉钉成员信息姓名怎么修改(钉钉成员信息姓名怎么改)

    钉钉成员信息姓名怎么修改(钉钉成员信息姓名怎么改)

  • iphone12自带键盘震动怎么开(苹果12键盘不见了)

    iphone12自带键盘震动怎么开(苹果12键盘不见了)

  • 独显和集显的区别有哪些(独显和集显的区别怎么区分啊)

    独显和集显的区别有哪些(独显和集显的区别怎么区分啊)

  • 华为荣耀play3语音助手如何唤醒(华为荣耀play3语音助手能用语音唤醒嘛)

    华为荣耀play3语音助手如何唤醒(华为荣耀play3语音助手能用语音唤醒嘛)

  • airpods打开盖子无显示(airpods打开盖子橙色灯闪烁)

    airpods打开盖子无显示(airpods打开盖子橙色灯闪烁)

  • iphone11面容录入一直显示在低一点(苹果11面容录入不了是什么原因)

    iphone11面容录入一直显示在低一点(苹果11面容录入不了是什么原因)

  • 京东注册了店铺会员怎么取消(京东注册了店铺怎么取消)

    京东注册了店铺会员怎么取消(京东注册了店铺怎么取消)

  • 淘宝不想退款了怎么处理(淘宝退款不想退了怎么办)

    淘宝不想退款了怎么处理(淘宝退款不想退了怎么办)

  • oppoa9屏幕尺寸(oppoa9屏幕尺寸多大)

    oppoa9屏幕尺寸(oppoa9屏幕尺寸多大)

  • 手机能播放TF片吗(手机能播flv吗)

    手机能播放TF片吗(手机能播flv吗)

  • 华为mate30pro录音功能在哪里(华为mate30pro录音文件删除还能找回吗)

    华为mate30pro录音功能在哪里(华为mate30pro录音文件删除还能找回吗)

  • 微信怎么设置拒绝添加(微信怎么设置拒绝语音视频聊天)

    微信怎么设置拒绝添加(微信怎么设置拒绝语音视频聊天)

  • 中文操作系统适用于英文操作吗(中文版操作系统)

    中文操作系统适用于英文操作吗(中文版操作系统)

  • 拼多多的牧场怎么打开(拼多多的牧场怎么退出)

    拼多多的牧场怎么打开(拼多多的牧场怎么退出)

  • 华为手机mate30和pro的区别(华为手机Mate30和Mate40有啥区别)

    华为手机mate30和pro的区别(华为手机Mate30和Mate40有啥区别)

  • 塞罕坝在哪里(塞罕坝在哪里?塞罕坝景区有什么好玩的?怎样去塞罕坝?)

    塞罕坝在哪里(塞罕坝在哪里?塞罕坝景区有什么好玩的?怎样去塞罕坝?)

  • 淘宝账户余额在哪里看(淘宝里账户余额在哪里)

    淘宝账户余额在哪里看(淘宝里账户余额在哪里)

  • 朋友圈拉黑显示什么(微信朋友圈拉黑显示)

    朋友圈拉黑显示什么(微信朋友圈拉黑显示)

  • honor8c是什么手机(honor8a是什么手机)

    honor8c是什么手机(honor8a是什么手机)

  • 手机爱奇艺预约在哪里(爱奇艺的预约)

    手机爱奇艺预约在哪里(爱奇艺的预约)

  • 8p信号不好怎么解决(8p信号不稳定)

    8p信号不好怎么解决(8p信号不稳定)

  • 140940(140940kg是多少吨)

    140940(140940kg是多少吨)

  • vivo双系统怎么设置(vivo双系统怎么解除)

    vivo双系统怎么设置(vivo双系统怎么解除)

  • 手机快速充电设置在哪(手机快速充电设置在哪荣耀)

    手机快速充电设置在哪(手机快速充电设置在哪荣耀)

  • 新版Edge浏览器如何调整标签页指定睡眠时间(新版edge浏览器文字不显示)

    新版Edge浏览器如何调整标签页指定睡眠时间(新版edge浏览器文字不显示)

  • flex 布局:实现一行固定个数,超出强制换行(流式布局)(flex布局实现垂直居中)

    flex 布局:实现一行固定个数,超出强制换行(流式布局)(flex布局实现垂直居中)

  • 外贸企业申报退税流程
  • 增值税应纳税额的计算
  • 利润表中的所得税
  • 所得税汇算清缴时间期限
  • 税后工资怎么查
  • 出口退税三类企业指什么意思
  • 其他应收款利息收入会计分录怎么写
  • 收到红字专票怎么做账务处理
  • 增值税不达起征点处理
  • 职工发放福利的会计处理
  • 企业注销未抵扣完的进项税
  • 一般纳税人转登记为小规模纳税人
  • 长期股权投资权益法初始成本的确定
  • 黄金以旧换新怎么算费用
  • 原材料暂估分录
  • 有开发票就要交印花税吗?
  • 以前年度的税务怎么查
  • 小型微利企业所得税优惠政策
  • 绿化费用明细
  • 外资企业投资国内企业程序
  • 出口退税免退税
  • 出售原材料属于营业收入吗
  • 资金筹集业务的账务处理重点笔记
  • 办公家具折旧年限及计算方法
  • 有什么好方法可以让小孩子少吃糖
  • 电脑任务栏图标怎么全部显示出来
  • 外籍人员个税免征吗
  • php对象赋值给变量
  • php从哪里开始学
  • 成本结转的科目
  • 分期收款销售商品,收到本期货款50万元
  • 原 !神静态网页布局详解,html+css布局实战,附详细代码
  • 以不动产作价出资入股
  • php字符串比较大小
  • 超市购物增值税怎么算
  • 第三方代付如何开票
  • vue 长列表优化
  • mac配置flutter环境变量
  • is-l命令
  • php数据库搭建
  • phpcms栏目分类
  • 红冲费用如何处理
  • 公司捐款怎样抵扣
  • 财务费用的具体内容
  • php是免费的吗
  • 年末未分配利润减去年初未分配利润等于什么
  • 综合所得汇算清缴是什么意思
  • 股份支付属于应付职工薪酬吗?
  • mysql出现的问题
  • 安防工程注意事项有哪些
  • 母公司设立子公司协议
  • 其他业务收入的附加税的会计分录
  • 增值税开票系统怎么改开票人名字信息
  • 基本工资和什么挂钩
  • 主营业务收入一定要结转成本吗
  • sql多表连接查询(详细实例)
  • microsoft window vista
  • CentOS操作系统
  • win8优化驱动器
  • linux进程和线程底层实现原理一样吗
  • 电脑光驱怎么装系统w7
  • win10无法uefi
  • 禁止windows安装程序
  • mac怎么共享网络给iphone
  • c盘越来越小了
  • javascript重点
  • js文件设置编码
  • shell脚本-p
  • js动态生成html页面
  • jquery自定义函数
  • js几种类型
  • bootstrap4 教程
  • javascrip
  • 单张发票开票限额?
  • 税务八项规定日期怎么写
  • 小汽车碰撞游戏视频
  • 发票号码应与哪个号码一致
  • 四川省地方税务局
  • 纳税人分类分级管理办法
  • 耕地占用税应该什么时候交
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设