Thread中方法
- 注意为什么sleep()、currentThread()、interrupted()、yield()这些方法是静态方法,因为设计一个线程的run()方法的时候,需要改变当前线程的状态,而当前线程对象未定义完毕无法调用函数,在这种情况下可以直接调动静态方法(等同于当前线程直接调用了该方法),或者调用currentThread()方法来获取当前线程对象。
如:
public static void main(String[] args) {
Thread t = new Thread(() ->{
try {
Thread.sleep(1000);
int result = A/B;
//错误:The local variable t may not have been initialized
t.join();
System.out.println(result);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
1、setDaemon
- setDaemon(boolean on): 将该线程标记为守护线程或用户线程。
- 当前线程结束,守护线程也跟着结束
- 必须在调用start()方法前,调用setDaemon方法
2、 优先级
- getId(): 返回该线程的标识符。
- getPriority(): 返回线程的优先级。
- setPriority(int newPriority): 更改线程的优先级。
3、join
- join(): 当前线程等待调用该方法线程结束,也就是让“主线程”等待“子线程”结束之后才能继续运行。
- join(time): 当前线程等到调用该方法多长时间
- Thread.currentThread().join(): 当前线程等待当前线程的结束,程序处于一直运行的状态
- 是封装了wait方法
- join相比wait而言,join是只能让当前线程等待,而wait可以让任意调用这个函数的线程等待。
- 根据底层实现原理,只要调用这个函数的“子线程”一直没死亡,那么会一直调用这个函数,使得当前线程一直等待,直到“子线程”结束没法在调用join函数为止
更多资料:https://www.cnblogs.com/skywang12345/p/3479275.html
join 和 Daemon对比
join是等待一个线程结束后在执行当前线程,Daemon是守护线程和当前线程并发进行。
4、中断线程 interrupt interrputed
- 可以中断wait()、sleep()、或者join()方法
- 中断并不是指直接中断run方法,只是中断wait()、sleep()、join()方法返回一个异常,run还能正常执行
- interrupt()是实例方法
- interrupted()是类方法,测试当前线程是否已经中断,底层调用的还是isInterrupted()
https://blog.csdn.net/z69183787/article/details/25076033
https://blog.csdn.net/zhuyong7/article/details/80852884
对比: interrupt() interrupted()
public class CreateThread {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
public void run() {
while (true) {
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
System.out.println("收到打断信号.");
//调用的是实例方法
System.out.println(isInterrupted()); //false
}
}
}
};
t.start();
Thread.sleep(1000);
System.out.println(t.isInterrupted()); //false
t.interrupt(); //中断了sleep()方法,但是run()方法并未中断
System.out.println(t.isInterrupted()); //true
}
}
public class CreateThread {
private static final Object MONITOR = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() ->{
while(true) {
synchronized(MONITOR) {
try {
MONITOR.wait(10);
} catch (InterruptedException e) {
//调用的是 currentThread().isInterrupted(true)
// interrupted是静态方法
System.out.println(">> "+Thread.interrupted());
}
}
}
});
t.start();
Thread.sleep(1000);
System.out.println(t.isInterrupted());
t.interrupt();
System.out.println(t.isInterrupted());
}
}
总结:
当Thread是直接重写run方法的时候,可以直接调用isInterrupted方法,相当于this.isInterrupted().
当Thread中传入的是Runnable的时候,在Runnable中的run方法中不能调用实例方法,因为run方法是封装在RUnnable接口里面,在这种情况下,只能调用类的方法。
中断join方法
- 调用join的是当前线程,不是实例线程
代码示例:
public class CreateThread {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
public void run() {
while(true) {
}
}
};
t.start();
Thread main = Thread.currentThread();
Thread t2 = new Thread() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//真正要打断的是main线程,才能打断join方法
main.interrupt();
System.out.println("Interrupt");
}
};
t2.start();
try {
//真正调用join()方法的是当前的线程main,并不是t线程
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
5、 yield
参考链接:https://blog.csdn.net/dabing69221/article/details/17426953
- 使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。
- 让出CPU的执行权
- 之后所有线程(包括让出的这一线程)同时竞争CPU的执行权。
打个比方:现在有很多人在排队上厕所,好不容易轮到这个人上厕所了,突然这个人说:“我要和大家来个竞赛,看谁先抢到厕所!”,然后所有的人在同一起跑线冲向厕所,有可能是别人抢到了,也有可能他自己有抢到了。我们还知道线程有个优先级的问题,那么手里有优先权的这些人就一定能抢到厕所的位置吗? 不一定的,他们只是概率上大些,也有可能没特权的抢到了。
public class YieldTest extends Thread {
public YieldTest(String name) {
super(name);
}
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println("" + this.getName() + "-----" + i);
// 当i为30时,该线程就会把CPU时间让掉,让其他或者自己的线程执行(也就是谁先抢到谁执行)
if (i == 30) {
this.yield();
}
}
}
public static void main(String[] args) {
YieldTest yt1 = new YieldTest("张三");
YieldTest yt2 = new YieldTest("李四");
yt1.start();
yt2.start();
}
}
注意:这个不存在线程安全的问题,因为i是局部变量(是每个线程自己所私有的),不存在数据共享的问题。
单个线程也不存在线程安全的问题,代码是按照顺序执行(当然在底层会改变一些数据,但是代码执行的逻辑并未发生改变),所以单个线程会依次打印出1——50
运行结果:
李四-----1
张三-----1
李四-----2
张三-----2
李四-----3
张三-----3
李四-----4
张三-----4
李四-----5
张三-----5
李四-----6
张三-----6
李四-----7
张三-----7
李四-----8
张三-----8
李四-----9
张三-----9
张三-----10
张三-----11
张三-----12
张三-----13
张三-----14
张三-----15
张三-----16
张三-----17
张三-----18
张三-----19
张三-----20
张三-----21
张三-----22
张三-----23
张三-----24
张三-----25
张三-----26
张三-----27
张三-----28
张三-----29
张三-----30
李四-----10
李四-----11
李四-----12
李四-----13
李四-----14
李四-----15
李四-----16
李四-----17
李四-----18
李四-----19
李四-----20
李四-----21
李四-----22
李四-----23
李四-----24
李四-----25
李四-----26
李四-----27
李四-----28
李四-----29
李四-----30
张三-----31
张三-----32
张三-----33
张三-----34
张三-----35
张三-----36
张三-----37
张三-----38
张三-----39
张三-----40
张三-----41
张三-----42
张三-----43
张三-----44
张三-----45
张三-----46
张三-----47
张三-----48
张三-----49
张三-----50
李四-----31
李四-----32
李四-----33
李四-----34
李四-----35
李四-----36
李四-----37
李四-----38
李四-----39
李四-----40
李四-----41
李四-----42
李四-----43
李四-----44
李四-----45
李四-----46
李四-----47
李四-----48
李四-----49
李四-----50