一、Thread中”run()“与start()的区别,多不多说直接上代码
package com.huawei.bes.demo;
import com.sun.org.apache.xpath.internal.SourceTree;
/**
* Created by lenovo12 on 2018/11/3.
*/
public class ThreadTT extends Thread{
@Override
public void run()
{
try {
System.out.println("run ThreadName = " + this.currentThread().getName() + " begin .");
Thread.sleep(2000);
System.out.println("run threadName = " + this.currentThread().getName() + " end .");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ThreadTT lThread = new ThreadTT();
System.out.println("main begin " + System.currentTimeMillis());
lThread.run();
System.out.println(" main end " + System.currentTimeMillis());
}
}
运行结果如下,我们可以发现虽然我们创建了以下新的线程,但是调度run方法的还是 调度main方法的名字叫做”main“的这个线程所以依旧还是同步的
接着我们换成start方法,代码中仅仅是将run 换成了 start,代码如下。
package com.huawei.bes.demo;
import com.sun.org.apache.xpath.internal.SourceTree;
/**
* Created by lenovo12 on 2018/11/3.
*/
public class ThreadTT extends Thread{
@Override
public void run()
{
try {
System.out.println("run ThreadName=" + this.currentThread().getName() + " begin .");
Thread.sleep(2000);
System.out.println("run threadName=" + this.currentThread().getName() + " end .");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ThreadTT lThread = new ThreadTT();
System.out.println("main begin " + System.currentTimeMillis());
lThread.start();
System.out.println("main end " + System.currentTimeMillis());
}
}
运行结果如下,由于 main 线程 与 我们ThreadTT这个线程这时是异步执行的,所以先打印的是main的begin 和end这两个语句,ThreadTT线程随后运行的,在最后打印了run begin 与 run end
所以Thread类中run()和start()方法的区别如下:
-
run()方法:在本线程内调用该Runnable对象的run()方法,可以重复多次调用;
-
start()方法:启动一个线程,调用该Runnable对象的run()方法,不能多次启动一个线程;
二、suspend 与 resume 方法被废弃的原因
直接上代码
package com.huawei.bes.demo;
import com.sun.org.apache.xpath.internal.SourceTree;
/**
* Created by lenovo12 on 2018/11/3.
*/
public class ThreadTT extends Thread{
private int i;
@Override
public void run()
{
while(true)
{
i++;
// System.out.println(i);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTT t = new ThreadTT();
t.start();
t.sleep(1);
t.suspend();
System.out.println("end");
}
}
运行结果如下,线程t被暂停了。
现在将System.out.println(i);这个输出语句打开,代码如下
package com.huawei.bes.demo;
import com.sun.org.apache.xpath.internal.SourceTree;
/**
* Created by lenovo12 on 2018/11/3.
*/
public class ThreadTT extends Thread{
private int i;
@Override
public void run()
{
while(true)
{
i++;
System.out.println(i);
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTT t = new ThreadTT();
t.start();
t.sleep(1);
t.suspend();
System.out.println(Thread.currentThread().getName() +"end");
}
}
再次运行,结果如下一直循环打印 i 的值 ,直至线程被暂停。但是发现main方法中 end 这个语句没有打印出来,原来println这个方法加了synchronized 关键字修饰,也就是加了锁,线程暂停了一直没有释放锁,所以这个end就打印不出来了,这也就是suspend 与 resume 方法的缺点, 会独占。
/**
* Prints a String and then terminate the line. This method behaves as
* though it invokes <code>{@link #print(String)}</code> and then
* <code>{@link #println()}</code>.
*
* @param x The <code>String</code> to be printed.
*/
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
yield方法的用法与作用
yield方法的作用是使线程放弃当前CPU的资源,将之让给其他的线程去占用CPU,但是放弃的时间是不确定的,并且放弃了还是可以继续抢占CPU资源的,也就是说可能刚放弃又马上获得可CPU时间片。代码如下
package com.huawei.bes.demo;
import com.sun.org.apache.xpath.internal.SourceTree;
/**
* Created by lenovo12 on 2018/11/3.
*/
public class ThreadTT extends Thread{
private int i;
@Override
public void run()
{
long startTime = System.currentTimeMillis();
while(true)
{
i++;
//Thread.yield();
if(i == 500000)
break;
}
long endTime = System.currentTimeMillis();
System.out.println("用时"+ (endTime - startTime) + "毫秒");
}
public static void main(String[] args) throws InterruptedException {
ThreadTT t = new ThreadTT();
t.start();
}
}
运行结果如下
这时将 Thread.yield() 这行代码放开得到如下结果,说明将CPU让给了其他资源导致耗时更长了