多线程学习笔记 第一章 (二)
- 停止线程
- 暂停线程
- yield()方法
- 线程优先级
- 守护线程
停止线程
使用interrupt()方法(停止不了的线程)
先来看如何判断线程是否已经停止的两个方法interrupted()和isInterrupted()
/**
* 测试Interrupted方法和Isinterrupted方法的区别
*/
public class Code_16_InterruptedAndIsinterruptedTest {
private static class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 5000; i++) {
System.out.println("i = " + (i + 1));
}
}
}
public static void main(String[] args) {
System.out.println("-----------test1---------");
test1();
System.out.println("-----------test2---------");
test2();
System.out.println("-----------test3---------");
test3();
}
public static void test1(){
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep(1000);
thread.interrupt();
//Thread.currentThread().interrupt();
System.out.println("是否停止 1 ="+thread.interrupted()); //false
System.out.println("是否停止 2 ="+thread.interrupted());//false
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
/**
* 当前线程是主线程 可以停止 但是第二层为false的原因是interrupted有清除的作用
*/
public static void test2(){
Thread.currentThread().interrupt();//停掉当前main线程
System.out.println("是否停止 1 =" + Thread.interrupted());//true
System.out.println("是否停止 2 =" + Thread.interrupted());//false
System.out.println("end!");
}
/**
* isInterrupted方法的使用
*/
public static void test3(){
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep(1000);
thread.interrupt();
System.out.println("是否停止 1 ="+thread.isInterrupted());//false
System.out.println("是否停止 2 ="+thread.isInterrupted());//false
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
第一个两个false的输出是因为当前线程是main线程,没有停止,第二个停止了主线程,但是第二个false是因为interrupted方法具有清除状态的功能。第三个isInterrupted没有这种功能。
停止线程方法:
- 可以使用异常法停止线程
- 在沉睡中停止(sleep方法在fun方法的内部)
- 使用stop暴力停止(不推荐)
- 使用Return和Interrupt来停止线程
package ThreadCoreTechnology.chapter1;
/**
* 使用异常法停止线程
*/
public class Code_17_StopForCatchTest {
private static class MyThread extends Thread {
@Override
public void run() {
super.run();
try {
for (int i = 0; i < 500000; i++) {
if (this.interrupted()) {
System.out.println("已经是停止状态了,要退出了!");
throw new InterruptedException();
}
System.out.println("i=" + (i + 1));
}
System.out.println("我在for的下面! ");
} catch (InterruptedException e) {
System.out.println("进MyThread.java类中的run 方法的catch了!");
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep(3000);
thread.interrupt();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
/**
* 使用Return 和Interrupt来结束线程
*/
public class Code_18_ReturnInterruptedTest {
private static class MyThread extends Thread {
@Override
public void run() {
while (true) {
if (this.isInterrupted()) {
System.out.println("停止了!");
return; //结束
}
System.out.println("timer = " + System.currentTimeMillis());
}
}
}
public static void main(String[] args) throws InterruptedException {
MyThread t=new MyThread();
t.start();
Thread.sleep(2000);
t.interrupt(); //使用interrupt和return 来结束
}
}
暂停线程
暂停线程意味着恢复,可以suspend方法暂停线程,使用resume()方法恢复线程的执行。
suspend()方法也容易造成不同步的,所以使用要非常的小心。
yield()方法
查看下面代码:
/**
* 放弃当前的CPU资源,让给其他的任务
*/
public class Code_19_YieldTest {
private static class MyThread extends Thread {
@Override
public void run() {
long beginTime = System.currentTimeMillis();
int count = 0;
for (int i = 0; i < 50000000; i++) {
// Thread.yield();
count = count + (i + 1);
}
long endTime = System.currentTimeMillis();
System.out.println("用时: " + (endTime - beginTime) + "毫秒!");
}
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
不加yield()方法输出:
用时: 26毫秒!
加上yield()方法输出:
用时: 20217毫秒!
线程优先级
具有三个特性:
- 继承性
- 规则性
- 随机性
(1)线程优先级具有继承性:
/**
* 线程优先级 具有继承性
*/
public class Code_20_PriorityTest {
private static class MyThread1 extends Thread {
@Override
public void run() {
System.out.println("MyThread1 run priority=" + this.getPriority());
MyThread2 thread2 = new MyThread2();
thread2.start();
}
}
private static class MyThread2 extends Thread {
@Override
public void run() {
System.out.println("MyThread2 run priority=" + this.getPriority());
}
}
public static void main(String[] args) {
System.out.println("main thread begin priority="
+ Thread.currentThread().getPriority());
Thread.currentThread().setPriority(6);
System.out.println("main thread end priority="
+ Thread.currentThread().getPriority());
MyThread1 thread1 = new MyThread1();
thread1.start();
}
}
效果
(2)线程优先级具有规则性:
- 高优先级的线程总是大部分代码先执行完,但不代表高优先级的线程全部先执行完;
- 优先级和代码的执行顺序无关(优先级的差距很大的时候),说明优先级具有一定的规则性,也就是CPU尽量将资源让给优先级比较高的线程;
(3)线程优先级具有随机性
守护线程
看下面的代码:
/**
* 守护线程
*/
public class Code_21_DaemonTest {
private static class MyThread extends Thread {
private int i = 0;
@Override
public void run() {
try {
while (true) { //本来是一直打印
i++;
System.out.println("i = " + (i));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.setDaemon(true); //设置守护线程 //如果注释掉这一句就会一直打印,
thread.start();
Thread.sleep(5000);
System.out.println("我离开thread对象再也不打印了,也就是停止了!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
代码中thread.setDaemon(true); 如果注释掉这一句就会一直打印,因为设置了这个之后,线程休眠,守护线程没有了,就结束了。