新建线程
新建线程很简单。只要使用new关键字创建一个线程对象,并且将它start()起来即可。
public static void main(String[] args) { Thread thread = new Thread();// thread.run(); thread.start();}
线程start()后会做什么这才是问题关键,线程Thread有一个run()方法,star()方法就会新建一个线程并让这个线程执行run()方法。但要注意:如果放开run()方法去掉start()方法也可以正常编译执行,但是却不能新建一个线程,而且当前线程中调用run()方法,只是作为一个普通的方法调用。这就是start()和run()方法的区别。
上述代码Thread的run()方法什么都没有做线程已启动马上就结束了。如果要让线程做点什么,就必须重载run()方法,把你要做的事情放进去。
public static void main(String[] args) { Thread thread = new Thread() { @Override public void run(){ System.out.println("HELLO 张三"); } }; thread.start();}
但考虑到java是单继承,因此我们也可以使用Runnable接口来实现同样的操作。Runnable它只有一个run()方法。默认的Thread.run()就是直接调用内部的Runnable接口。因此,使用Runnable接口告诉该线程该做什么,更为合理。
public class ThreadTest2 implements Runnable{ @Override public void run() { System.out.println("Hello 李四"); } public static void main(String[] args) { Thread thread = new Thread(new ThreadTest2()); thread.start(); }}
上述代码实现了Runnable接口,并将该实例传入Thread。这样避免重载Thread.run,单纯使用接口来定义Thread也是最常见的做法。
终止线程
使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果),因为stop()太过暴力,强行把执行一般的线程终止,可能会引起一些数据不一致的问题。
thread.stop();
并不推荐使用这种方法来终止线程。
线程中断
与线程中断有三种有关的方法,这三个方法看起来很像,所以可能会引起混淆和误用,希望注意
//中断线程public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { interrupt0(); b.interrupt(this); return; } } interrupt0();}//判断是否被中断public static boolean interrupted() {return currentThread().isInterrupted(true);}//判断是否被中断,并清除当前中断状态public boolean isInterrupted() {return isInterrupted(false);}
interrupt,名字看上去很像是终止一个线程的方法,但是我可以很明确地告诉大家,它不能终止一个正在执行着的线程,它只是修改中断标志而已,例如下面一段代码:
public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread() { @Override public void run() { while (true) { System.out.println("张三"); Thread.yield(); } } }; t1.start(); t1.interrupt();}
执行这段代码,你会发现一直有Running在输出,似乎执行了 interrupt没有任何变化。虽然t1进行了中断,但是在t1中没有中断处理的逻辑,因此,即使t1县城被置上了终端状态,但是这个中断不会发生任何作用,如果希望t1在中断后退出,就必须为它增加相应的中断处理代码。如下所示:
public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread() { @Override public void run() { while (true) { if (Thread.currentThread().isInterrupted()){ System.out.println("已中断"); break; } System.out.println("张三"); Thread.yield(); } } }; t1.start(); t1.interrupt();}
总之如果期望终止一个正在运行的线程,则不能使用已经过时的Stop方法,需要自行 编码实现,如此即可保证原子逻辑不被破坏,代码逻辑不会出现异常。当然,如果我们使用的是线程池(比如ThreadPoolExecutor类),那么可以通过shutdown方法逐步关闭池中的线 程,它采用的是比较温和、安全的关闭线程方法,完全不会产生类似stop方法的弊端。