1、线程终止
1.1、基本说明
- 当线程完成任务后,会自动退出
- 还可以通过使用变量来控制run方法退出的方式停止线程,即通知方式
1.2、代码演示
package exit_;
public class ThreadExit {
public static void main(String[] args) throws InterruptedException {
T t1 = new T();
t1.start();
// 如果希望main线程去控制t1 线程的终止, 必须可以修改 loop
// 让t1 退出run方法, 从而终止 t1线程 -> 通知方式
// 让主线程休眠 10 秒, 再通知 t1线程退出
System.out.println("main线程休眠10s...");
Thread.sleep(10 * 1000);
t1.setLoop(false);
}
}
class T extends Thread {
private int count = 0;
// 设置一个控制变量
private boolean loop = true;
@Override
public void run() {
while (loop) {
try {
Thread.sleep(50); // 让当前线程休眠50ms
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T 运行中...." + (++count));
}
}
public void setLoop(boolean loop) {
this.loop = loop;
}
}
2、线程常用方法
2.1、常用方法第一组
package method;
public class ThreadMethod01 {
public static void main(String[] args) throws InterruptedException {
// 测试相关的方法
T t = new T();
t.setName("jack");
// 更改线程的优先级
t.setPriority(Thread.MIN_PRIORITY); // 1
t.start(); // 启动子线程
// 主线程打印5 hi, 然后我就中断 子线程的休眠
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
System.out.println("hi " + i);
}
System.out.println(t.getName() + " 线程的优先级" + t.getPriority()); // 1
t.interrupt(); // 当执行到这里, 就会中断 t线程的休眠
}
}
class T extends Thread { // 自定义的线程类
@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() + " 休眠中~~~");
Thread.sleep(20000); // 20秒
} catch (InterruptedException e) {
// 当该线程执行到一个interrupt 方法时, 就会catch 一个 异常, 可以加入自己的业务代码
// InterruptedException 是捕获到一个中断异常
System.out.println(Thread.currentThread().getName() + "被 interrupt了");
}
}
}
}
2.2、注意事项和细节
2.3、常用方法第二组
package method;
public class ThreadMethod02 {
public static void main(String[] args) throws InterruptedException {
T2 t2 = new T2();
t2.start();
for (int i = 0; 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 {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(1000); // 1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程(老大) 吃了 " + i + " 包子");
}
}
}
2.4、小练习
package method;
public class ThreadMethodExercise {
public static void main(String[] args) throws InterruptedException {
Thread t3 = new Thread(new T3());
for (int i = 0; i < 10; i++) {
System.out.println("hi " + i);
if (i == 5) { // 说明主线程输出了 5 次 hi
t3.start(); // 启动子线程 输出 hello...
t3.join(); // 立即将 t3 子线程, 插入到 main 线程, 让 t3 先执行
}
Thread.sleep(1000); // 输出一次 hi, 让 main 线程也休眠 1s
}
}
}
class T3 implements Runnable {
private int count = 0;
@Override
public void run() {
while (true) {
System.out.println("hello " + (++count));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 10) break;
}
}
}
3、用户线程和守护线程
3.1、应用案例
测试如何将一个线程设置成守护线程
package method;
public class ThreadMethod03 {
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 {
@Override
public void run() {
for (; ; ) { // 无限循环
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("马蓉和宋喆快乐聊天,哈哈哈~~~");
}
}
}