当前位置:网站首页>线程基础(一)
线程基础(一)
2022-08-02 05:11:00 【谁是黄黄】
活动地址:CSDN21天学习挑战赛
文章目录
一.并发与并行的概念
1.程序:一个固定逻辑与数据的集合就是程序 例如 俄罗斯方块 贪吃蛇
2.cpu:中央处理器 主要用于协调程序与硬件的工作
那什么是并发与并行?
先来一张图浅显了解一下并发和并行的区别吧。
大体上的解释是:
并发(又称高并发):是同一个时间段
执行两个,或者两个以上程序
的,单核cpu
交互(上面所说的时间片轮转是一种)的执行,由于cpu切换的速度很快,逻辑
上我们任务并发是同时执行
多个任务,实际
上是交替执行
。
例子:两个队伍的人在一个窗口打菜。
并行:在同一时刻,执行两个或者是多个程序
的时候,多核cpu同时执行
(现象的电脑都是多核cpu)
例子:多个人在多个咖啡机前排队。
二.线程与进程
概念:
进程:运行在内存
中的程序
就是进程.
每个进程都有⼀个独⽴的内存空间,⼀个应⽤程序可以同时运⾏多个进程;进程也是程序的⼀次执⾏过程,是系统运⾏程序的基本单位;系统运⾏⼀个程序即是 ⼀个进程从创建、运⾏到消亡的过程
线程: 通向cpu的执行的路径
就是线程。
线程又分为单线程和多线程
单线程:只有一条通向cpu的执行的路径
多线程:多条通向cup的执行的路径
注意:
1.一个进程中能包含多个线程
2.一个线程只能存在一个进程中。
3.任务管理器里关闭的那个玩意就叫做进程
多线程的进程运行的流程图
三. 主线程与子线程
3.1主线程:
主方法中,例如运行main方法函数的线程
负责管理子线程,即子线程的启动、挂起、停止等等操作
public class HelloWorld {
public static void main(String[] args) {
Thread mainThread = Thread.currentThread();
System.out.println("我是主线程");
}
}
3.2子线程:
只能是理解为由主线程负责管理,即主线程负责启动,挂起,停止的线程为子线程
3.3进程,主线程,子线程的关系图
四.线程的三种创建方法
4.1 第一种 继承Thread重写run方法
步骤:
1.定义一个类去继承Thread
2.重写run()方法,执行线程的操作
3.实例化这个线程类的独享
4.调用start()方法,开启线程
public class MyThread extends Thread{
@Override
public void run() {
for (int i=1;i<=10;i++){
System.out.println(i);
}
}
}
测试类
public class Testhuang {
public static void main(String[] args) {
//实例化对象
MyThread myThread = new MyThread();
myThread.start();
}
}
输出结果:
4.2第二种 实现Runnable接口
步骤:
1.定义一个类 实现 Runnable
2.实现run()
3.实例化线程对象 Thread 传递一个参数 Runnable 的实现类
4.调用方法开启线程 start()
线程定义类
public class MyRunnable implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i);
}
}
}
测试类
public class Testhuang {
public static void main(String[] args) {
//实例化Runnable对象的实现类
MyRunnable r = new MyRunnable(); //实例化线程类
Thread th = new Thread(r); //开启线程
th.start();
}
}
结果
4.3第三种 实现Callable接口
步骤
:
1.定义一个类实现接口 Callable
2.重写call()方法
3.实例化 任务对象 FutureTask 构建一个Callable的实现类
4.实例化线程对象 Thread 构建一个任务对象
5.开启线程
6.调用任务对象的get() 获取其返回值
实现线程类
public class MyCallAble implements Callable<Integer> {
@Override
public Integer call() throws Exception {
Integer sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
return sum;
}
}
测试类
public class Testhuang {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallAble call = new MyCallAble();
FutureTask<Integer> f = new FutureTask<>(call);
Thread t = new Thread(f);
t.start();
Integer c = f.get();
System.out.println(c);
}
}
结果
4.4 最常用的创建线程的方式
使用Runnable的匿名内部类来创建线程
public class Testhuang {
public static void main(String[] args) {
//第一种方式
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}).start();
//第二种方式
new Thread(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName());
}
}.start();
}
}
结果
4.5 线程调度的方式
线程调度
的方式有两种
:
1.分配式调度:多个线程执行任务的时间,都是评价分配,每一个线程执行的周期都是相同的
2.抢占式调度:线程的优先级越高,获取cpu执行权越高,线程抢到cpu的概率
就越搞,优先执行的概率就越高,而我们的java
中的多线程
就是抢占式调度
例子:
创建线程类
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
try {
//sleep方法是休眠方法,这里间隔0.1s
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//.getName方法获取当前线程的名称
System.out.println(Thread.currentThread().getName() + "\t" + i);
}
}
}
测试类:
public class Testhuang {
public static void main(String[] args) {
//开启第一个线程
MyThread th1 = new MyThread();
th1.start();
//开启第二个线程
MyThread th2 = new MyThread();
System.out.println(th2);
}
}
4.5线程的内存图
4.7 线程的常见方法
4.7.1 获取线程名
方法名 | 作用 |
---|---|
public final String getName() | 返回该线程的名称 |
public static Thread currentThread() | 返回对当前正在执行的线程对象的引用 |
线程创建类
public class MyThread extends Thread {
@Override
public void run(){
for (int i = 0; i < 10; i++) {
System.out.println(getName() + "\t" + i);
}
}
}
测试类
public class Testhuang {
public static void main(String[] args) {
//实例化线程对象
MyThread th = new MyThread();
th.start();
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i);
}
}
}
结果
4.7.2 线程休眠
方法名 | 作用 |
---|---|
public static void sleep(long millis) | 线程休眠 |
线程创建类
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 60; i >= 1; i--) {
System.out.println("还剩下" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试类
public class Testhuang {
public static void main(String[] args) {
//实例化线程对象
MyThread th = new MyThread();
th.start();
}
}
结果
4.7.3 守护线程
方法名 | 作用 |
---|---|
public final void setDaemon(boolean on) | 设置为守护线程 |
public final boolean isDaemon() | 测试该线程是否为守护线程 |
线程创建类
public class MyThread extends Thread {
@Override
public void run() {
try {
//休眠五秒
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
OutputStream is = new FileOutputStream("3.txt");
is.write(97);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试类
public class Testhuang {
public static void main(String[] args) {
//实例化线程对象
MyThread my = new MyThread();
//设置为守护线程
my.setDaemon(true);
//获取其状态
System.out.println(my.isDaemon());
my.start();
try {
Thread.sleep(6000);
} catch (
InterruptedException e) {
e.printStackTrace();
}
}
}
结果
显示开启了守护线程
4.7.4 设置线程的优先级
4.7.4.1 常量
常量名 | 作用 |
---|---|
public static final int MAX_PRIORITY | 线程可以具有的最高优先级 |
public static final int MIN_PRIORITY | 线程可以具有的最低优先级 |
public static final int NORM_PRIORITY | 分配给线程的默认优先级 |
注意点
:
1.线程的
最高优先级
是10
,最低优先级
是1
,范围1-10
2.线程优先级越高
表示获取cpu执行权越大
即被执行的概率越高,但是并不一定会执行
,因为java是抢占式调度
4.7.4.2 方法
方法名 | 作用 |
---|---|
public final int getPriority() | 返回的是线程的优先级 |
public final void setPriority(int newPriority) | 更改线程的优先级 |
线程创建类
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(getName() + "\t" + i);
}
}
}
测试类
public class Testhuang {
public static void main(String[] args) {
//实例化第一个线程
MyThread t = new MyThread();
t.setPriority(8);
t.start(); //
// 实例化第二个线程
MyThread th = new MyThread();
th.setPriority(Thread.MAX_PRIORITY);
th.start();
}
}
结果
边栏推荐
- Browser onload event
- Redis-----非关系数据库
- The original question on the two sides of the automatic test of the byte beating (arranged according to the recording) is real and effective 26
- classSR论文阅读笔记
- Mysql常用命令大全
- Introduction to coredns
- navicat connects to MySQL and reports an error: 1045 - Access denied for user 'root'@'localhost' (using password YES)
- 网安学习-内网渗透4
- C language entry combat (13): decimal number to binary
- 如何优化OpenSumi终端性能?
猜你喜欢
随机推荐
ERROR 1045 (28000) Access denied for user 'root'@'localhost'Solution
H5 access payment process - WeChat payment & Alipay payment
Introduction and use of apifox (1).
测试技术之APP蓝牙连接测试
TikTok平台的两种账户有什么区别?
C语言中i++和++i在循环中的差异性
C语言小游戏——扫雷小游戏
对node工程进行压力测试与性能分析
自动化运维工具——ansible、概述、安装、模块介绍
golang泛型
Polar Parametrization for Vision-based Surround-View 3D Detection 论文笔记
浏览器的onload事件
LeetCode brush topic series - 787 K station transfer within the cheapest flight
上海交大牵手淘宝成立媒体计算实验室:推动视频超分等关键技术发展
navicat connects to MySQL and reports an error: 1045 - Access denied for user 'root'@'localhost' (using password YES)
18 years of programmer career, read more than 200 programming books, pick out some essence to share with you
家用 NAS 服务器(4)| MergerFS和SnapRaid数据定时备份
C竞赛训练
【漫画】2021满分程序员行为对照表(最新版)
MYSQL unique constraint