Java线程中的静态方法_Java多线程4:Thread中的静态方法
发布日期:2021-06-24 19:28:02 浏览次数:2 分类:技术文章

本文共 7223 字,大约阅读时间需要 24 分钟。

一、Thread类中的静态方法

Thread类中的静态方法是通过Thread.方法名来调用的,那么问题来了,这个Thread指的是哪个Thread,是所在位置对应的那个Thread嘛?通过下面的例子可以知道,Thread类中的静态方法所操作的线程是“正在执行该静态方法的线程”,不一定是其所在位置的线程。为什么Thread类中要有静态方法,这样就能对CPU当前正在运行的线程进行操作。下面来看一下Thread类中的静态方法:

1、currentThread()

/*** Returns a reference to the currently executing thread object.

*

*@returnthe currently executing thread.*/

public static native Thread currentThread();

currentThread()方法返回的是对当前正在执行的线程对象的引用。

举例:

public class Thread01 extendsThread{static{

System.out.println("静态代码块的打印:" +Thread.currentThread().getName());

}publicThread01(){

System.out.println("构造函数的打印:" +Thread.currentThread().getName());

}

@Overridepublic voidrun() {

System.out.println("run方法的打印:" +Thread.currentThread().getName());

}

}

public classTest {public static voidmain(String[] args){

Thread01 thread01= newThread01();

thread01.start();

}

}

结果:

静态代码块的打印:main

构造函数的打印:main

run方法的打印:Thread-0

可以看到,Thread01类中的三个相同的静态方法Thread.currentThread()所操作的不是同一个线程,虽然写在了Thread01内,但是静态代码块和构造函数中的静态方法是随着main线程而被调用的,run方法中的静态方法则是thread01线程调用的。把thread01.start()注释掉

public classTest {public static voidmain(String[] args){

Thread01 thread01= newThread01();//thread01.start();

}

}

结果:

静态代码块的打印:main

构造函数的打印:main

因为Thread01中的静态代码块和构造方法都是在main线程中被调用的,而run方法是thread01这个线程调用的,所以不一样。

举例说明上篇说的"this.XXX()"和"Thread.currentThread().XXX()"的区别,this表示的线程是线程实例本身,后一种表示的线程是正在执行"Thread.currentThread.XXX()这块代码的线程"

public class Thread01 extendsThread{publicThread01(){

System.out.println("构造函数中通过this调用:" + this.getName());

System.out.println("构造函数中通过静态方法调用:" +Thread.currentThread().getName());

}

@Overridepublic voidrun() {

System.out.println("run方法中通过this调用:" + this.getName());

System.out.println("run方法中通过静态方法调用:" +Thread.currentThread().getName());

}

}

public classTest {public static voidmain(String[] args){

Thread01 thread01= newThread01();

thread01.start();

}

}

结果:

构造函数中通过this调用:Thread-0构造函数中通过静态方法调用:main

run方法中通过this调用:Thread-0run方法中通过静态方法调用:Thread-0

同样的,把thread01.start()这一行注释掉以后

public classTest {public static voidmain(String[] args){

Thread01 thread01= newThread01();//thread01.start();

}

}

结果:

构造函数中通过this调用:Thread-0构造函数中通过静态方法调用:main

所以,在Thread01里面通过Thread.currentThread得到的线程对象的引用不一定就是Thread01,要看该方法所在的代码会被哪个线程调用。

2、sleep(long millis)

/*** Causes the currently executing thread to sleep (temporarily cease

* execution) for the specified number of milliseconds, subject to

* the precision and accuracy of system timers and schedulers. The thread

* does not lose ownership of any monitors.

*

*@parammillis

* the length of time to sleep in milliseconds

*

*@throwsIllegalArgumentException

* if the value of {@codemillis} is negative

*

*@throwsInterruptedException

* if any thread has interrupted the current thread. The

* interrupted status of the current thread is

* cleared when this exception is thrown.*/

public static native void sleep(long millis) throws InterruptedException;

sleep(long millis)方法的作用是在指定的毫秒内让当前"正在执行的线程"休眠(暂停执行)。这个"正在执行的线程"是关键,指的是Thread.currentThread()返回的线程。根据JDK API的说法,"该线程不丢失任何监视器的所属权",简单说就是sleep代码上下文如果被加锁了,锁依然在,但是CPU资源会让出给其他线程。

举例:

public class Thread01 extendsThread{

@Overridepublic voidrun() {try{

System.out.println("run threadName:" + this.getName());

System.out.println("调用Thread.sleep方法休眠3秒");

Thread.sleep(3000);

System.out.println("run threadName:" +Thread.currentThread().getName());

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

public classTest {public static voidmain(String[] args){

System.out.println("main 开始===" +System.currentTimeMillis());

Thread01 thread01= newThread01();

thread01.start();

System.out.println("main 结束=====" +System.currentTimeMillis());

}

}

结果:

main 开始===1552401515206main 结束=====1552401515208run threadName:Thread-0调用Thread.sleep方法休眠3秒

run threadName:Thread-0

3、yield()

/*** A hint to the scheduler that the current thread is willing to yield

* its current use of a processor. The scheduler is free to ignore this

* hint.

*

*

Yield is a heuristic attempt to improve relative progression

* between threads that would otherwise over-utilise a CPU. Its use

* should be combined with detailed profiling and benchmarking to

* ensure that it actually has the desired effect.

*

*

It is rarely appropriate to use this method. It may be useful

* for debugging or testing purposes, where it may help to reproduce

* bugs due to race conditions. It may also be useful when designing

* concurrency control constructs such as the ones in the

* {@linkjava.util.concurrent.locks} package.*/

public static native void yield();

暂停当前执行的线程,并执行其他的线程。这个暂停是会放弃CPU资源的,并且放弃CPU的时间不确定,有可能刚放弃,就获得CPU资源了,也有可能放弃好一会儿,才会被CPU执行。

举例说明yield()放弃CPU的时间是不一定的,用户无法指定

public class Thread01 extendsThread{

@Overridepublic voidrun() {for(int i = 1; i <= 500; i++) {long beginTime =System.currentTimeMillis();

Thread.yield();long endTime =System.currentTimeMillis();

System.out.println(" 第" + i + "次yield 的时长为:" + (endTime - beginTime) + "ms");

System.out.println("i = " +i);

}

}

}

public class Thread02 extendsThread{

@Overridepublic voidrun() {for(int i = 0; i < 500000; i++) {

List list = new ArrayList<>();

list.add(i);

}

}

}

public classTest {public static voidmain(String[] args) {

Thread01 thread01= newThread01();

thread01.start();//根据Thread02多开几个线程

Thread02 thread02 = newThread02();

thread02.start();

Thread02 thread021= newThread02();

thread021.start();

Thread02 thread022= newThread02();

thread022.start();

Thread02 thread023= newThread02();

thread023.start();

Thread02 thread024= newThread02();

thread024.start();

}

}

结果:

.......................................

.......................................

i= 48第48次yield 的时长为:0ms

i= 49第49次yield 的时长为:0ms

i= 50第50次yield 的时长为:1ms

i= 51第51次yield 的时长为:0ms

i= 52第52次yield 的时长为:4ms

i= 53第53次yield 的时长为:0ms

i= 54第54次yield 的时长为:0ms

.......................................

.......................................

i= 442第442次yield 的时长为:0ms

i= 443第443次yield 的时长为:0ms

i= 444第444次yield 的时长为:1ms

i= 445第445次yield 的时长为:0ms

i= 446第446次yield 的时长为:0ms

.......................................

.......................................

可以看到,yield()方法放弃CPU的时间是不确定的,可能立马就被CPU执行,也可能要等待一会再被CPU执行。

4、interrupted()

/*** Tests whether the current thread has been interrupted. The

* interrupted status of the thread is cleared by this method. In

* other words, if this method were to be called twice in succession, the

* second call would return false (unless the current thread were

* interrupted again, after the first call had cleared its interrupted

* status and before the second call had examined it).

*

*

A thread interruption ignored because a thread was not alive

* at the time of the interrupt will be reflected by this method

* returning false.

*

*@returntrue if the current thread has been interrupted;

* false otherwise.

*@see#isInterrupted()

* @revised 6.0*/

public static booleaninterrupted() {return currentThread().isInterrupted(true);

}

测试当前线程是否处于中断状态,调用该方法,线程中断状态的标识被清除(置为false),也就是说,如果这个方法被连续调用两次,第二次一定会返回false

public classTest {public static voidmain(String[] args) {

Thread.currentThread().interrupt();

System.out.println(Thread.currentThread().getName()+ "线程是否被中断?" +Thread.interrupted());

System.out.println(Thread.currentThread().getName()+ "线程是否被中断?" +Thread.interrupted());

}

}

结果:

main线程是否被中断?truemain线程是否被中断?false

当然,这也涉及Java的中断机制,留在后面的一篇文章专门讲解。

参考资料:

转载地址:https://blog.csdn.net/weixin_34262786/article/details/114523029 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:java swt书_可视化JavaSWT/JFaceGUI程序设计教程——基于EclipseWindowBuilder开发环境(21世纪高等学校规划教材·计算机应用)...
下一篇:java enum 序号_java-通过传递预设序号来获取枚举值

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年05月01日 20时11分59秒