当前位置:网站首页>面试官:并发编程实战会吗?(线程控制操作详解)
面试官:并发编程实战会吗?(线程控制操作详解)
2022-07-05 21:05:00 【Trouvailless】
前言
在使用Java实际编程中,多线程可以说是无所不在,凡是需要并发执行的都可以用到它,一个应用程序中不用多线程将会是很糟糕的事情,所以 掌握线程以及它的控制操作是非常重要的 。
通过本篇文章来今天带大家一文掌握线程控制操作,感谢您的观看。
目录
:pencil2:
:pencil2:
一、线程的基本概念
1.并行和并发
并行:多个CPU核心同时工作,处理不同的任务。
并发:多个任务交替使用 CPU 核心工作,以提高 CPU 利用率。
2.进程和线程
进程:程序的一次执行。由操作系统创建并分配资源,执行一个单独的任务。
进程是系统进行资源分配和调度的独立单位,每个进程都有自己的内存空间和系统资源。进程内所有线程共享堆存储空间,保存程序中定义的对象和常量池。
Windows系统中,每个运行的 Java 程序都是一个独立的进程。
线程:进程内的执行单元,不分配单独的资源,执行一个单独的子任务。
线程是进程内调度和分派的基本单位,共享进程资源。每个线程有自己的独立的栈存储空间,保存线程执行的方法以及基本类型的数据。
运行的 Java 程序内含至少一个主线程 main ,用户可以在 Java 程序中自定义并调用多个线程。JVM 垃圾回收线程也是一个独立的线程。
二、线程的运行状态
线程除创建状态 New 和结束状态 Terminate 外,主要有以下几种运行状态:
①运行(Running) :CPU 正在执行线程。
②就绪(Runnable) :线程一切就绪,等待 CPU 执行。
运行/就绪状态 统称为可运行状态 Runnable。Java 程序中,线程在 运行/就绪状态 之间的切换由 JVM 自动调度,开发者无法获知。线程之间的调度采用分优先级多队列时间片轮转算法。进程在执行完 CPU 时间片切换到就绪状态之前会先保存自己的状态,下次进入运行状态时再重新加载。
③阻塞(Blocked) :线程因缺少其他资源,比如请求资源被上锁而暂停执行。在获得资源后进入就绪状态。
④等待(Waitting) :线程接受了等待指令,释放资源暂停执行。在超时/接受唤醒指令后进入就绪状态。
三、线程操作实践
Runnable 接口内唯一声明了 run 方法,由 Thread 类实现。开发者在 run 方法中定义运行时线程将要执行的功能,线程开启后由Java虚拟机自动调用并执行。如果开发者主动调用 run 方法,则只会当作普通方法执行。
1.线程两种定义方法
①继承 Thread 类,重写 run 方法。
public class MyThread extends Thread { @Override
public void run() { System.out.println(Thread.currentThread().getName());
}
}
②实现 Runnable 接口,实现 run 方法。推荐使用,避免了单继承的局限性。
public class MyThread implements Runnable { @Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
2.启动线程
Thread 类定义了 start 方法。调用 start 方法后,系统会开启一个新线程进入就绪状态:由 JVM 会自动对线程进行调度,在运行时调用并执行线程的 run 方法。一个线程只能启动一次。
①如果自定义线程类继承 Thread 类,直接启动。
public class Main { public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread("ThreadName");
t1.start();
t2.start();
}
}
②如果自定义线程类实现 Runnable 接口,则需要借助 Thread 类启动线程。
public class Main { public static void main(String[] args) {
MyThread mythread = new MyThread();
Thread t1 = new Thread(mythread); // 由系统指定默认线程名 Thread-X
Thread t2 = new Thread(mythread, "ThreadName"); // 开发者自定义线程名
t1.start();
t2.start();
}
}
3.同时定义和启动线程
通过匿名内部类方式,我们可以实现同时定义和启动线程的简洁写法。
public class Main { public static void main(String[] args) {
Thread thread = new Thread(new Runnable(){ public void run(){
System.out.println(Thread.currentThread().getName());
}
}).start();
}
}class Test { public void method() {
System.out.println(Thread.currentThread().getName());
}
}
4.线程弹出与暂停
Thread 类定义了 yield 方法。当前线程执行到 Thread.yield()
方法,会停止运行进入就绪状态。但线程切换到就绪状态后,什么时候被 JVM 调度回运行状态开发者无法控制。
public class ThreadDemo { public static void main(String[] args) {
MyThread mythread = new MyThread();
Thread t1 = new Thread(mythread);
Thread t2 = new Thread(mythread);
t1.start();
t2.start();
} static class MyThread implements Runnable { @Override
public void run() { int count = 0; for (int i = 0; i < 10000; i++) {
Thread.yield(); // 切换到就绪状态
count++;
System.out.println(count);
}
}
}
}
Thread 类定义了 sleep 方法。当前线程执行到 Thread.sleep(1000)
方法,会停止运行进入阻塞状态,但仍会保持对象锁,其他线程不可访问其资源。直到超时后进入就绪状态。调用 sleep 方法需要捕获或抛出 InterruptException 异常。
public class ThreadDemo { public static void main(String[] args) {
MyThread mythread = new MyThread();
Thread t1 = new Thread(mythread);
Thread t2 = new Thread(mythread);
t1.start();
t2.start();
} static class MyThread implements Runnable { @Override
public void run() { int count = 0; for (int i = 0; i < 10000; i++) { try{
Thread.sleep(1000); // 当前线程暂停 1s
} catch(InterruptException e){
e.printStackTrace();
}
count++;
System.out.println(count);
}
}
}
}
5.线程等待与唤醒
①线程等待
当前线程执行 obj.wait()
方法,线程会停止运行并释放对象锁 obj,其他线程可以访问其资源。同时线程进入 obj 对象的等待池,直到被 notify 方法唤醒进入就绪状态。调用 wait 方法需要捕获或抛出 InterruptException 异常。
wait 方法允许计时等待。当前线程执行 obj.wait(1000)
方法,计时结束后线程会被自动唤醒进入就绪状态。
②线程唤醒
当前线程执行 obj.notify()
方法,会随机从 obj 对象等待池中选择一个线程唤醒,使其进入就绪状态。但是 notify 方法不会释放当前进程的对象锁,如果该线程持有 obj 对象的锁,当前线程释放锁后被唤醒的其他线程才能被执行。如果想被唤醒线程先执行,notify 方法后添加 wait 方法释放锁。
当前线程执行 obj.notifyall()
方法,会将所有 obj 对象等待池中所有线程唤醒。
public class ThreadDemo { public static void main(String[] args) {
MyThread t = new MyThread("t"); synchronized(t) { // 对 t 设置对象锁
try {
t.start();
System.out.println("1");
t.wait(); // 当前线程释放 t 锁,进入 t 对象等待池
System.out.println("4");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} static class MyThread extends Thread { @Override
public void run() { synchronized (this) { // 对 t 设置对象锁
Thread.sleep(1000);
System.out.println("2"); this.notify(); // 随机唤醒一个 t 对象等待池中的线程
System.out.println("3");
}
}
}
}
6.线程中断
调用 t.stop()
方法可以强制终止线程 t 运行,但强制中断线程可能会造成意想不到的问题,已不推荐使用。
目前主要采用设置线程中断标志的方式,向线程发送中止信号。由线程自行终止运行:
t.interrupt()t.isInterrupted()t.interrupted()
public class ThreadDemo { public static void main(String[] args) {
MyThread mythread = new MyThread();
Thread t = new Thread(mythread);
t.start(); try {
Thread.sleep(500);
} catch (InterruptedException e) {}
t.interrupt(); // 设置中断标志为 true
} static class MyThread implements Runnable { @Override
public void run() { while (true) {
System.out.print("hello"); if(this.isInterrupted()){ // 查看中断标志,若为 true 结束循环
break;
}
}
}
}
}
接下来给大家分享本份文档内容涵盖: Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、 Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、Linux等技术栈,共1000多道面试题。
需要的小火伴可在下方公众号货区
以下只是Java并发编程一个知识点
边栏推荐
- Learning robots have no way to start? Let me show you the current hot research directions of robots
- Binary search
- 驱动壳美国测试UL 2043 符合要求有哪些?
- AITM2-0002 12s或60s垂直燃烧试验
- MySQL 千万数据量深分页优化, 拒绝线上故障!
- Influence of oscilloscope probe on signal source impedance
- 学习机器人无从下手?带你体会当下机器人热门研究方向有哪些
- 研學旅遊實踐教育的開展助力文旅產業發展
- PVC plastic sheets BS 476-6 determination of flame propagation properties
- PVC 塑料片BS 476-6 火焰传播性能测定
猜你喜欢
CLion配置visual studio(msvc)和JOM多核编译
haas506 2.0开发教程 - 阿里云ota - pac 固件升级(仅支持2.2以上版本)
[case] Application of positioning - Taobao rotation map
ArcGIS栅格重采样方法介绍
五层网络协议
基於flask寫一個接口
基于vertx-web-sstore-redis的改造实现vertx http应用的分布式session
实现浏览页面时校验用户是否已经完成登录的功能
LeetCode_哈希表_困难_149. 直线上最多的点数
R language [data management]
随机推荐
The reason why the ncnn converted model on raspberry pie 4B always crashes when called
Influence of oscilloscope probe on measurement bandwidth
Pytoch practice -- MNIST dataset handwritten digit recognition
Determine the best implementation of horizontal and vertical screens
XML建模
【日常训练--腾讯精选50】89. 格雷编码(看题解才会的)
leetcode:1139. 最大的以 1 为边界的正方形
haas506 2.0开发教程 - 阿里云ota - pac 固件升级(仅支持2.2以上版本)
The development of research tourism practical education helps the development of cultural tourism industry
Material design component - use bottomsheet to show extended content (II)
Pytorch实战——MNIST数据集手写数字识别
木板ISO 5660-1 热量释放速率摸底测试
Sequence alignment
Is it necessary for bazel to learn
EN 438-7 laminated sheet products for building covering decoration - CE certification
Clion-MinGW编译后的exe文件添加ico图标
Cutting edge technology for cultivating robot education creativity
Open source SPL eliminates tens of thousands of database intermediate tables
Binary search
国外LEAD美国简称对照表