Java重修笔记 第五十四天 坦克大战(四)多线程基础
-
线程
当点击运行按钮运行程序时,就相当于启动了一个进程,虚拟机进入 mian 方法后会开启一个名为 mian 的主线程,main 方法体中创建一个线程对象,调用该线程对象的 start 方法又创建一个子线程,子线程的启动并不会阻塞主线程剩余代码继续执行。
主线程结束后并不会影响进程的结束,只有当该进程下的所有线程全部结束后,该进程才会结束。
-
Jconsole 工具的使用
在程序运行时,打开下面的 Terminal 终端显示框,输入 Jconsole 便可打开监视和管理控制台,其中便可找到对应线程查看状态。
若无法看到本地线程,可参考以下文章解决:
运行jconsole无法看到本地进程_jconsole找不到本地进程-CSDN博客文章浏览阅读1.2k次,点赞3次,收藏3次。设置完全控制_jconsole找不到本地进程https://blog.csdn.net/weixin_49107940/article/details/127963204
-
关于 start 方法
只有调用线程对象 start 方法才能创建出一个子线程,子线程不影响主线程的执行,如果只调用线程对象的 run 方法,那就不会创建新线程,还是在主线程中运行,阻塞主线程直到 run 方法执行完毕。
start 方法底层会调用 start0 方法,此方法才真正实现多线程的效果。当然 start0 并不会直接创建线程,而是将线程的状态改变为“可运行状态”,具体什么时候执行,取决于CPU统一调度。
-
创建线程
1. 通过继承 Thread 类来创建线程
(1)让对象类继承 Thread 类,而 Thread 类实现了 Runnable 接口,该类就可以当做一个线程使用
(2)重写 Runnable 接口里的 run 方法,在方法体中写上自己的业务逻辑
(3)创建线程类对象,调用线程类对象的 start 方法来启动该线程,启动子线程后并不会阻塞主线程下面的代码继续执行
public class Thread01 {public static void main(String[] args) {Cat cat = new Cat();cat.start();try {for (int i = 0; i < 10; i++) {Thread.sleep(1000);System.out.println("主线程输出第" + i + "次");}} catch (InterruptedException e) {System.out.println(e.getMessage());}}
}class Cat extends Thread {private static int count;@Overridepublic void run() {do {count++;System.out.println("第" + count + "次输出, 线程名为: " + Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {System.out.println(e.getMessage());}} while (count != 80);}
}
2. 通过实现 Runnable 接口来创建线程
(1)让对象类实现 Runnable 接口
(2)重写 Runnable 接口里的 run 方法,在方法体中写上自己的业务逻辑
(3)创建线程类对象,然后创建 Thread 类对象,把线程类对象作为参数放到 Thread 类的构造方法中(静态代理模式)
(4)调用 Thread 类对象的 start 方法
public class Thread02 {public static void main(String[] args) {new Thread(new Dog()).start();}
}class Dog implements Runnable {public static int count = 0;@Overridepublic void run() {try {do {count++;System.out.println("第" + count + "次输出, 线程名为: " + Thread.currentThread().getName());Thread.sleep(1000);} while (count < 80);} catch (InterruptedException e) {System.out.println(e.getMessage());}}
}
-
线程退出-通知方式
简单来说就是在线程类中设置一个变量,并向外暴露修改方法,通过线程对象的 set 方法来操作这个变量,以实现手动控制 run 方法退出这个子线程。
public class ThreadExit_ {public static void main(String[] args) {MyThread04 myThread04 = new MyThread04();myThread04.start();// 主线程休眠 10 秒后退出子线程try {Thread.sleep(1000 * 10);} catch (InterruptedException e) {e.printStackTrace();}myThread04.setLoop(false);}
}class MyThread04 extends Thread {private boolean loop = true;private int count = 0;public boolean isLoop() {return loop;}public void setLoop(boolean loop) {this.loop = loop;}@Overridepublic void run() {try {while (loop) {if (count++ == 1000) {break;}Thread.sleep(100);System.out.println(Thread.currentThread().getName() + "运行中... " + count);}} catch (InterruptedException e) {e.printStackTrace();}}
}