第三次学JAVA再学不好就吃翔(part115)--多线程
学习笔记,仅供参考,有错必纠
文章目录
- 多线程
- 多线程引入
- 什么是线程
- 多线程并行和并发的区别
- Java程序运行原理
- 多线程的实现方式
- 多线程实现的方式1
- 多线程程序实现的方式2
- 以上两种实现方式的区别
- 获取和设置线程名字
- 获取当前线程对象
- 休眠线程
- 守护线程
- 加入线程
- 礼让线程(略)
多线程
多线程引入
什么是线程
线程是程序执行的一条路径, 一个进程中可以包含多条线程;多线程并发执行可以提高程序的效率,可以同时完成多项工作。
多线程并行和并发的区别
并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行;
并发是指两个任务都请求运行,而处理器只能按受一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行。
Java程序运行原理
Java命令会启动java虚拟机,启动JVM就等于启动了一个应用程序,也就是启动了一个进程;
该进程会自动启动一个主线程
,然后主线程去调用某个类的main
方法;
同时,JVM启动至少启动了垃圾回收线程和主线程,所以是多线程的。
多线程的实现方式
多线程实现的方式1
- 继承Thread
- 定义继承Thread类的类;
- 重写
run
方法; - 把新线程要做的事写在
run
方法中; - 创建线程对象;
- 开启新线程, 内部会自动执行
run
方法。
- 举个例子
package com.guiyang.restudy3;public class D2Thread {public static void main(String[] args) {MyThread mt = new MyThread(); //4,创建Thread类的子类对象mt.start(); //5,开启线程for (int i = 0; i <= 1000; i++) {System.out.println("yyy");}}}class MyThread extends Thread { //1,继承Threadpublic void run() { //2,重写run方法for (int i = 0;i <= 1000; i++) { //3,将要执行的代码写在run方法中System.out.println("xxxxxxxxxxx");}}
}
多线程程序实现的方式2
- 实现Runnable接口
- 定义实现Runnable接口的类;
- 实现run方法;
- 把新线程要做的事写在run方法中;
- 创建自定义的Runnable的子类对象;
- 创建Thread对象,将刚刚创建的Runnable子类对象传入Runnable;
- 调用
start()
开启新线程,Runnable的run()
方法被自动调用。
- 举个例子
package com.guiyang.restudy3;public class D3Thread {public static void main(String[] args) {MyRunnable mr = new MyRunnable(); //4,创建Runnable的子类对象Thread tr = new Thread(mr); //5,将其当作参数传递给Thread的构造函数tr.start(); //6,开启线程for (int i = 0; i <= 1000; i++) {System.out.println("yyy");}}}class MyRunnable implements Runnable { //1,定义一个类实现Runnable@Overridepublic void run() { //2,重写run方法for (int i = 0;i <= 1000; i++) { //3,将要执行的代码写在run方法中System.out.println("xxxxxxxxxxx");}}
}
以上两种实现方式的区别
在源码上的区别:
- 继承Thread : 由于子类重写了Thread类的
run()
, 当调用start()
时,直接找子类的run()
方法; - 实现Runnable : 构造函数中传入了Runnable的引用, 成员变量记住了它,
start()
调用run()
方法时,内部判断成员变量Runnable的引用是否为空,若不为空,编译时看的是Runnable的run()
,运行时执行的是子类的run()
方法。
继承Thread:
- 好处:可以直接使用Thread类中的方法,代码简单;
- 弊端:如果某类已经有了父类,就不能再继承Thread类了。
实现Runnable接口:
- 好处:即使自己定义的线程类有了父类也没关系,因为接口是可以多实现的;
- 弊端:不能直接使用Thread中的方法,需要先获取到线程对象后才能得到Thread的方法,代码复杂。
获取和设置线程名字
获取名字:通过getName()
方法获取线程对象的名字
设置名字:通过构造函数可以传入String类型的名字
- 举个例子
获取线程名字:
package com.guiyang.restudy3;public class D4ThreadName {public static void main(String[] args) {new Thread("安徽财经大学") { //通过构造方法给name赋值public void run() {System.out.println(this.getName() + "...xxx");}}.start();new Thread("安徽医科大学") {public void run() {System.out.println(this.getName() + "....yyyyyyyy");}}.start();}}
控制台输出:
安徽财经大学...xxx
安徽医科大学....yyyyyyyy
设置线程名字:
package com.guiyang.restudy3;public class D4ThreadName {public static void main(String[] args) {Thread t1 = new Thread() {public void run() {System.out.println(this.getName() + "...yyyyyyyyy");}};Thread t2 = new Thread() {public void run() {System.out.println(this.getName() + "...xxx");}};t1.setName("财经大学");t2.setName("医科大学");t1.start();t2.start();}}
控制台输出:
财经大学...yyyyyyyyy
医科大学...xxx
获取当前线程对象
获取当前线程对象:
package com.guiyang.restudy3;public class D5GetThreadObject {public static void main(String[] args) {new Thread(new Runnable() {public void run() {for(int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "...bb");}}}).start();Thread.currentThread().setName("我是主线程"); //获取主函数线程的引用,并改名字System.out.println(Thread.currentThread().getName()); //获取主函数线程的引用,并获取名字}}
控制台输出:
我是主线程
Thread-0...bb
Thread-0...bb
Thread-0...bb
Thread-0...bb
Thread-0...bb
休眠线程
休眠线程:
package com.guiyang.restudy3;public class D5GetThreadObject {public static void main(String[] args) {new Thread() {public void run() {for(int i = 0; i < 5; i++) {System.out.println(getName() + "...yyyyyyyyyyy");try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}}.start();new Thread() {public void run() {for(int i = 0; i < 5; i++) {System.out.println(getName() + "...xxx");try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}}.start();}}
控制台输出:
Thread-0...yyyyyyyyyyy
Thread-1...xxx
Thread-0...yyyyyyyyyyy
Thread-1...xxx
Thread-0...yyyyyyyyyyy
Thread-1...xxx
Thread-0...yyyyyyyyyyy
Thread-1...xxx
Thread-0...yyyyyyyyyyy
Thread-1...xxx
守护线程
设置矩阵论
线程和数值分析
为守护线程,当非守护线程执行完毕后,守护线程则都自动退出:
package com.guiyang.restudy3;public class D5GetThreadObject {public static void main(String[] args) {Thread t1 = new Thread("数理统计") {public void run() {for(int i = 0; i < 3; i++) {System.out.println(getName() + "...xxx");try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}};Thread t2 = new Thread("数值分析") {public void run() {for(int i = 0; i < 15; i++) {System.out.println(getName() + "...xxx");try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}};Thread t3 = new Thread("矩阵论") {public void run() {for(int i = 0; i < 15; i++) {System.out.println(getName() + "...yyyyyyyy");try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}};t2.setDaemon(true); //将t2和t3设置为守护线程t3.setDaemon(true);t1.start();t2.start();t3.start();}}
控制台输出:
数值分析...xxx
矩阵论...yyyyyyyy
数理统计...xxx
数值分析...xxx
数理统计...xxx
矩阵论...yyyyyyyy
矩阵论...yyyyyyyy
数理统计...xxx
数值分析...xxx
矩阵论...yyyyyyyy
数值分析...xxx
加入线程
设置当前线程暂停,等待指定的线程执行结束后,当前线程再继续:
package com.guiyang.restudy3;public class D5GetThreadObject {public static void main(String[] args) {final Thread t1 = new Thread() {public void run() {for(int i = 0; i < 6; i++) {System.out.println(getName() + "...yyyyyyyy");try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}};Thread t2 = new Thread() {public void run() {for(int i = 0; i < 6; i++) {if(i == 2) {try {t1.join(); //加入Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(getName() + "...xxx");}}};t1.start();t2.start();}}
控制台输出:
Thread-1...xxx
Thread-1...xxx
Thread-0...yyyyyyyy
Thread-0...yyyyyyyy
Thread-0...yyyyyyyy
Thread-0...yyyyyyyy
Thread-0...yyyyyyyy
Thread-0...yyyyyyyy
Thread-1...xxx
Thread-1...xxx
Thread-1...xxx
Thread-1...xxx
设置加入线程时间,在指定时间内插队完成后,两个线程继续交替执行:
package com.guiyang.restudy3;public class D5GetThreadObject {public static void main(String[] args) {final Thread t1 = new Thread() {public void run() {for(int i = 0; i < 7; i++) {System.out.println(getName() + "...yyyyyyyy");try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}};Thread t2 = new Thread() {public void run() {for(int i = 0; i < 6; i++) {if(i == 2) {try {t1.join(30); //插队30毫秒Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(getName() + "...xxx");}}};t1.start();t2.start();}}
控制台输出:
Thread-0...yyyyyyyy
Thread-1...xxx
Thread-1...xxx
Thread-0...yyyyyyyy
Thread-0...yyyyyyyy
Thread-0...yyyyyyyy
Thread-0...yyyyyyyy
Thread-1...xxx
Thread-1...xxx
Thread-1...xxx
Thread-1...xxx
Thread-0...yyyyyyyy
Thread-0...yyyyyyyy
礼让线程(略)
使用yield让出cpu:
package com.guiyang.restudy3;public class D5GetThreadObject {public static void main(String[] args) {new MyThread2().start();new MyThread2().start();}}class MyThread2 extends Thread {public void run() {for(int i = 1; i <= 100; i++) {if(i % 10 == 0) {Thread.yield(); //让出CPU}System.out.println(getName() + "..." + i);}}
}
第三次学JAVA再学不好就吃翔(part115)--多线程相关推荐
- 第三次学JAVA再学不好就吃翔(part117)--单例设计模式
学习笔记,仅供参考,有错必纠 文章目录 多线程 单例设计模式 饿汉式 懒汉式 第三种格式 Timer类 线程的五种状态 多线程 单例设计模式 单例设计模式,即保证类在内存中只有一个对象,如何保证类在内 ...
- 第三次学JAVA再学不好就吃翔(part107)--字符流的拷贝
学习笔记,仅供参考,有错必纠 文章目录 IO流 字符流的拷贝 拷贝纯文本文件 注意事项 自定义字符数组的拷贝 IO流 字符流的拷贝 拷贝纯文本文件 zzz.txt: 安徽财经大学 JAVA代码: pa ...
- 第三次学JAVA再学不好就吃翔(part106)--字符流
学习笔记,仅供参考,有错必纠 文章目录 IO流 字符流输入流FileReader 字符流是什么 FileReader类构造方法 举个例子 字符流输出流FileWriter FileWriter构造方法 ...
- 第三次学JAVA再学不好就吃翔(part46)--Scanner类
学习笔记,仅供参考 文章目录 Scanner类 Scanner获取数据出现的问题 Scanner类 概述 Scanner是在java.util包下的一个类,使用该类时我们需要导包.这个类被final修 ...
- 第三次学JAVA再学不好就吃翔(part109)--LineNumberReader类
学习笔记,仅供参考,有错必纠 IO流 LineNumberReader类 该类继承自java.io.BufferedReader,该类可以跟踪行号的缓冲字符输入流.此类定义了方法 setLineNum ...
- 第三次学JAVA再学不好就吃翔(part108)--带缓冲的字符流
学习笔记,仅供参考,有错必纠 文章目录 IO流 带缓冲的字符流 BufferedReader和BufferedWriter readLine和newLine方法 IO流 带缓冲的字符流 Buffere ...
- 第三次学JAVA再学不好就吃翔(part7)--基础语法之运算符
学习笔记,仅供参考 文章目录 JAVA基础语法 运算符 算数运算符 算术运算符 ++和-- 赋值运算符 关系运算符 JAVA基础语法 运算符 什么是运算符 就是对常量和变量进行操作的符号. 运算符的分 ...
- 第三次学JAVA再学不好就吃翔(part113)--对象操作流
学习笔记,仅供参考,有错必纠 对象操作流 对象操作流可以将一个对象写出, 或者读取一个对象到程序中,也就是执行了序列化和反序列化的操作. 举个例子 先构造一个Role类: package com.gu ...
- 第三次学JAVA再学不好就吃翔(part104)--flush和close
学习笔记,仅供参考,有错必纠 flush和close flush方法 对于写出数据来说,当缓冲区满了之后,缓冲区中的数据会自动写出,但是当缓冲区没有满时,调用flush方法,那么缓冲区就会被刷新,数据 ...
最新文章
- 重磅!AI Top 30+案例评选正式启动
- Oracle 12C 利用Rman Duplicate搭建 Data Guard
- tensorflow 使用CPU而不使用GPU的问题解决
- excel 粘贴了HTML怎么删掉,Excel怎么删除网页上复制删不掉的文本框
- 推荐几款不错的写作利器
- C语言二叉树曲折级顺序遍历(附完整源码)
- arcgis渔网分割提取栅格图_【操作】ArcGIS中字段的合并、分割、提取
- 组合框绑定字符串数组的数据 c# 1614236088
- 21种代码的“坏味道”
- BlueHost怎样创建MySQL数据库
- 对话Ruby创始人松本行弘、阿里高级技术专家朴灵!
- 用于 3d 渲染应用程序的常见物体 IOR(折射率)值
- [软件发布]2007考研倒计时软件(完整版+绿色版)
- http代表的是什么?http代表的是什么意思
- FreeRTOS死机原因
- 美国弗吉尼亚大学计算机科学,2017美国弗吉尼亚大学计算机科学专业
- 浅谈ERP项目团队管理的四个方面
- 自动表单生成工具说明(后端、桌面、web、移动端)
- Python 三人斗地主手牌生成
- HTML5 布局标签
热门文章
- codelite在 ubuntu6.04下开启C++11支持
- 5.11 加权Gram-Schmidt 分解
- python编程小知识_分享Python开发中要注意的十个小贴士
- python为什么这么火知乎_没想到 Google 排名第一的编程语言,为什么会这么火?...
- python怎么导入大小字母_isort-用于对python导入的库按照字母进行排序的工具
- 【bzoj3160】万径人踪灭
- C# asp:Repeater DataSource ListT
- 【转】The test form is only available for requests from the local machine 解决方法
- HT For Web 拓扑图背景设置
- rabbitmq 在centos下的安装