currentThread().getName()与this.getName()的区别
public static class MyThread extends Thread {
@Override
public void run() {
super.run();
System.out.println("cur__" + currentThread().getName() + "\nthis___" + this.getName());
}
}
public static void main(String args[]) {
MyThread myThread = new MyThread();
Thread a = new Thread(myThread, "A");
a.start();
}
输出结果:
cur__A
this___Thread-0
- currentThread().getName()获取的是当前运行的线程的名字,而this.getName()获取的是MyThread这个类的名字,MyThread继承Thread,从Thread的源码可以看出默认名字为:"Thread-"+num
停止线程:isInterrupted()与interrupted()
isInterrupted()与interrupted()都是测试线程是否停止,并不能真正的停止线程,只是标记作用。
public static class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 5000; i++) {
System.out.println("i = " + i);
}
}
}
public static void main(String args[]) {
try {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(30); // 注意这段代码,让子线程先跑,让下一段myThread.interrupt()生效
myThread.interrupt(); // 操作的是子线程,当前线程无法停止
System.out.println("是否停止"+myThread.isInterrupted()); // 子线程停止状态true
System.out.println("是否停止"+myThread.interrupted()); // 等同于Thread.interrupted()
Thread.currentThread().interrupt(); // 停止当前线程main
System.out.println("是否停止"+myThread.isInterrupted());
System.out.println("是否停止"+Thread.interrupted());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("end");
}
打印结果:
是否停止true
是否停止false
是否停止true
是否停止true
end
注意区分 结果分析:
- myThread.interrupted() 该方法内部实现为:currentThread().isInterrupted(true);使用等同于Thread.interrupted()。获取的是当前线程main的状态false。
- myThread.interrupt();// 不是当前线程无法停止 ------和----- Thread.currentThread().interrupt();--------如何理解呢?
源码解析:
myThread.interrupt();
Thread.currentThread().interrupt();
-----------以下为源码部分------------
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
只有代码所处执行位置为当前的线程才生效。因为例子中的myThread.interrupt();处于main的线程中,无法停止main线程。要停止main线程应该执行:Thread.currentThread().interrupt();
注意:
Thread.interrupted() 停止后会修改状态,恢复线程运行状态
myThread.isInterrupted() 停止后不会修改当前的运行状态
真正的停止线程
异常法
public static class MyThread extends Thread {
@Override
public void run() {
super.run();
try {
for (int i = 0; i < 5000; i++) {
if (interrupted()) { // 获取到停止标记位
System.out.println("停止状态,即将退出");
throw new InterruptedException();
}
System.out.println("i = " + i);
}
System.out.println("执行for之后的内容");
} catch (InterruptedException e) {
System.out.println("进入catch 方法");
e.printStackTrace();
}
}
}
public static void main(String args[]) {
try {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(30);
myThread.interrupt();// 不是当前线程无法停止
System.out.println("是否停止" + myThread.isInterrupted());
System.out.println("是否停止" + Thread.interrupted());
Thread.currentThread().interrupt();
System.out.println("是否停止"+Thread.interrupted()); // 重置标记位为false
System.out.println("是否停止" + Thread.currentThread().isInterrupted());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("end");
}
打印结果:
i = 2843
i = 2844
i = 2845
i = 2846
i = 2847
停止状态,即将退出
是否停止false
是否停止false
进入catch 方法
是否停止true
是否停止false
end
java.lang.InterruptedException
at TestThread$MyThread.run(TestThread.java:10)
Process finished with exit code 0
沉睡中停止
子线程在sleep()状态中调用interrupt()会终止子线程
public static class MyThread extends Thread {
@Override
public void run() {
super.run();
try {
System.out.println("begin...");
sleep(10000);
System.out.println("wakeup");
} catch (InterruptedException e) {
System.out.println("进入子线程catch 方法");
e.printStackTrace();
}
}
}
public static void main(String args[]) {
try {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(30); // 先sleep()再interrupt
myThread.interrupt();// 不是当前线程无法停止
System.out.println("是否停止" + myThread.isInterrupted());
} catch (Exception e) {
System.out.println("进入主线程catch 方法");
e.printStackTrace();
}
System.out.println("end");
}
打印结果:
begin...
进入子线程catch 方法
是否停止false
end
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at TestThread$MyThread.run(TestThread.java:8)
Process finished with exit code 0
结果分析:
- 子线程中不管是先sleep()再interrupt()还是先interrupt()再sleep(),都可以中断线程
暴力停止stop()
- 不建议使用stop()停止线程,因为stop()释放锁会造成数据不一致的问题。
暂停线程suspend和resume
-
注意:
- suspend和resume配合synchronize使用的话会造成公共的对象独占,使其他线程无法访问公共同步对象。
- println()
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
- println()源码中也有synchronize同步锁,使用请小心。
yield
Thread.yield();放弃当前的cpu资源,放弃时间不确定,也有可能刚刚放弃,又立马获取资源。