新建线程
新建线程很简单,只要使用new关键字创建一个线程对象,并且将它start()起来即可:
Thread t1 = new Thread();
t1.start();
注意:下面的代码也能通过编译和正常执行,但是却没有新建一个线程:
Thread t2 = new Thread();
t2.run();
这只是简单的普通方法调用,所以没有涉及新的线程创建。
那让我们来看看Thread的run方法里面是什么:
@Override
public void run() {
if (target != null) {
target.run();
}
}
这个target是什么呢:
/* What will be run. */
private Runnable target;
原来target就是一个Runnable,而这个Runnable是什么时候进行赋值的呢:
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
这是其中一个构造函数,可以看到当你在新建一个Thread时候,传入的Runnable传入init方法,在init内部可以看到这个Runnable是赋值给了上面所说的target,再来看回Thread的run方法:
@Override
public void run() {
if (target != null) {
target.run();
}
}
所以其实逻辑很简单,就是看你有没有传入一个Runnable,如果有就执行你传入的Runnable的run方法。
下面进行测试:
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {//这是实现Runnable接口的run方法
System.out.println(Thread.currentThread()+"runnable.run");
}
}){
@Override
public void run() {//这里是重写Thread的run方法
super.run();//默认的run方法是先判断Runnable是否为null,不为null就先执行Runnable中的run
System.out.println(Thread.currentThread()+"thread.run");
}
};
t1.start();
}
测试结果:
自己去试试吧!
关于中断
严格来说,线程中断并不会使线程立即退出,而是给线程发送一个通知,告知目标线程,至于目标线程接到通知后如何处理,则完成由目标线程自行决定。
public void Thread.interrupt() //中断线程
public boolean Thread.isInterrupted() //判断是否被中断
public static boolean Thread.interrupted() //判断是否被中断,并清除当前中断状态
测试:
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(true){
Thread.yield();
}
}
});
t.start();
t.interrupt();
}
这里虽然对线程t进行中断,但是t并没有中断处理的逻辑,因此就算t线程被置上了中断状态,这个中断也不会有任何作用。
如果希望线程t在中断后退出,就必须为它增加相应的处理代码:
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(true){
if(Thread.currentThread().isInterrupted()){
System.out.println("中断!");
break;
}
Thread.yield();
}
}
});
t.start();
t.interrupt();
}
这样就能达到响应中断的方法。
注意点:
Thread.sleep由于中断抛出异常,但是会清除中断标记:
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("睡眠被中断,已退出");
//Thread.sleep会清除中断标记
System.out.println(Thread.currentThread().isInterrupted());//false
//这里重新置上中断标记
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().isInterrupted());//true
}
}
});
t.start();
t.interrupt();
}
运行结果:
自己试试吧!