说明:参考《Java多线程核心技术》
4、基本概念
currentThread():可以返回代码段正在被那个线程调用的信息
isAlive():判断当前的线程是否处于活动状态
sleep():在指定的毫秒数内让当前"正在执行的线程"休眠
Runnable runnable = new Runnable01();
Thread thread = new Thread(runnable);
Thread.sleep(1000); // 休眠1000毫秒
thread.start();
5、停止线程
停止一个线程意味着在线程 处理完任务之前停掉正在做的操作。
三种停止一个线程的方法:
1、使用退出标志,使线程正常退出
2、使用stop方法。不推荐
3、使用interrupt()方法中断线程
调用interrupt()方法仅仅是在当前线程中打了一个停止的标记,并不是真的停止线程。
public class Runnable01 implements Runnable{
@Override
public void run() {
for (int i = 0 ; i < 100; i++) {
System.out.println(i);
}
System.out.println("--运行中...");
}
}
public class RunnableTest01 {
public static void main(String[] args) throws InterruptedException {
Runnable runnable = new Runnable01();
Thread thread = new Thread(runnable);
thread.start();
Thread.sleep(1000);
thread.interrupt();
System.out.println("--1" + Thread.interrupted());
System.out.println("是否真的停止了1--" + thread.isInterrupted());
System.out.println("还存活吗?--->" + thread.isAlive());
System.out.println("是否真的停止了2-->" + thread.isInterrupted());
System.out.println("--2" + Thread.interrupted());
System.out.println("--运行结束");
}
}
/***
99
--运行中...
--1false
是否真的停止了1--false
还存活吗?--->false
是否真的停止了2-->false
--2false
--运行结束
*/
this.interrupted():测试当前线程是否已经是中断状态,执行后将状态标志清除为false的功能
this.isInterrupted():测试线程Thread对象是个已经是中断状态,但不清除状态标志。
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
return isInterrupted(false);
}
释放锁的不良效果:使用已经过期的stop()方法见个会造成数据不一致的结果;
public class SynchronizedObject {
private String userName = "a";
private String passwoed = "aa";
//getter and setter and constructor
synchronized public void printString(String userName, String password) {
try {
this.userName = userName;
Thread.sleep(1000);
this.passwoed = password;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread extends Thread {
private SynchronizedObject object;
//constructor
public MyThread(SynchronizedObject object) {
super();
this.object = object;
}
@Override
public void run() {
object.printString("b", "bb");
}
}
public class SynchronizedObjectTest {
public static void main(String[] args) {
try {
SynchronizedObject object = new SynchronizedObject();
MyThread myThread = new MyThread(object);
myThread.start();
Thread.sleep(500);
// this is unSafe
myThread.stop();
System.out.println(object.getUserName() + "---" + object.getPasswoed());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
b---aa
*/
建议使用抛异常的方式开实现线程的停止,因为这种方式比较优雅,且使用异常能更方便的控制程序的流程。
6、暂停线程
在Java中,可以使用suspend()方法暂停线程,使用resume()方法恢复线程。
public class ResumeThread extends Thread{
private long i = 0;
// gettter and setter
@Override
public void run() {
while (true) {
i++;
}
}
}
public class ResumeThreadTest {
public static void main(String[] args) {
try {
ResumeThread thread = new ResumeThread();
thread.start(); // start a thread
Thread.sleep(5000);
// A phase
thread.suspend(); // suspend
System.out.println("A phase start time = " + System.currentTimeMillis() + "-->" + "i = " + thread.getI());
Thread.sleep(5000);
System.out.println("A phase end time = " + System.currentTimeMillis() + "-->" + "i = " + thread.getI());
// B phase
thread.resume(); // resume A phase
Thread.sleep(5000);
// C phase
thread.suspend(); // suspend B phase
System.out.println("B phase start time = " + System.currentTimeMillis() + "-->" + "i = " + thread.getI());
Thread.sleep(5000);
System.out.println("B phase end time = " + System.currentTimeMillis() + "-->" + "i = " + thread.getI());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
A phase start time = 1546434478303-->i = 1567745920
A phase end time = 1546434483310-->i = 1567745920
B phase start time = 1546434488318-->i = 3270786776
B phase end time = 1546434493326-->i = 3270786776
* */
线程确实被暂停了,而且还可以恢复成运行的状态。
yield()方法: 放弃当前的CPU资源,将其让给其他的任务去占用CPU执行时间。但是放弃的时间不确定,可能刚刚放弃,又立即获取到CPU的时间片。