是不是不管一个线程任务有多简单,都要重新new 一个java class ?当然不是,java 中线程的实现非常灵活,下面就具体讲下如何通过不同的方式来实现一个线程;
一、使用“Thread”+“有名内部类”来实现线程
public class InnerThread1 { private Inner inner; private class Inner extends Thread { Inner(String name) { super(name); this.start(); } public void run() { for( int i = 0; i < 5; i++) { System.out.println("Inner said : "+i); } } } public InnerThread1(String name) { ..... //InnerThread1 的其他业务逻辑 this.inner = new Inner(name); ..... //InnerThread1 的其他业务逻辑 } }
在InnnerThread1 中,每次实例化一个InnerThread1 对象,就会给它创建一个线程,来实现一些可以并发的任务。这里还在InnerThread1中 定义了一个内部类的引用,这样在InnerThread1 的其他方法中就可以使用这个引用来完成一些业务逻辑了。
二、使用”Thread“+”匿名内部类“的方式 来实现一个线程
同样,如果一个类只会new一次,那么使用匿名类会简化代码,是代码更简洁
public class AnonymousInnerThread { private Thread t; public AnonymousInnerThread(String name) { t = new Thread(name) { public void run() { for( int i = 0; i < 5; i++) { System.out.println("AnonymousInnerThread said : "+i); } } }; t.start(); } }
在接下来介绍的三和四中,如一、二的区别仅仅是把Thread 的实现方式改成了Runnable
三、Runnable+”有名内部类“的方式实现线程
public class NamedInnerRunnable { private Inner inner; public class Inner implements Runnable { Thread t; public Inner() { t = new Thread(this); //这里的this用的很销魂 t.start(); } @Override public void run() { for( int i = 0; i < 5; i++) { System.out.println("Inner thread said : "+i); } } } }
四、Runnable+”无名内部类“的方式实现线程
public class AnonymousInnerRunnable { Thread t; public AnonymousInnerRunnable() { t = new Thread(new Runnable(){ @Override public void run() { for( int i = 0; i < 5; i++) { System.out.println("Inner thread said : "+i); } } }); t.start(); } }五、在方法中实现线程,当想让线程工作的时候就直接调用该方法
public class CreateThreadInMethod { Thread t; public void startThread() { if( null == t){ t = new Thread(){ public void run() { for(int i = 0; i <10; i++) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Thread in method said: "+i); } } }; t.start(); } } }
另外提一下TimeUnit,它其实是一个枚举类型,使用TimeUnit.xxx.sleep()和Thread.sleep()的区别是,TimeUnit 可以根据XXX固定的时间粒度进行睡眠,而使用Thread.sleep只能计算到底要睡眠多少 ”毫秒“,也就是说Thread.sleep只有一种时间粒度,这样操作起来就非常不方便。
其实,TimeUnit在实现sleep方法的时候,只是根据XXX和睡眠时间帮我们换算成毫秒,然后还是调用Thread.sleep方法
好了,这一节就讲到这里啦。5种线程的实现方式(算上用外部类方式实现线程共有6种)各有好坏,这就需要在具体项目中根据实际情况来选用了。