为什么说本质上只有一种实现线程的方式?实现Runnable接口究竟比继承Thread类实现线程好在哪里?
1、实现Runnable接口
public class RunnableThread implements Runnable {@Overridepublic void run() {Sysout.out.print("用实现Runnable接口实现线程");}}
通过实现Runnable 接口的方式实现多线程
- 首先通过RunnableThread类实现Runnable接口
- 然后重写了run()方法
之后只要把这个实现了run()方法的实例传到Thread类中就可以实现线程
2、继承Thread类
public class ExtendsThread extends Thread {@Overridepublic void run() {Sysoutl.out.print("用Thread类实现线程")}}
与第一种方法不同的是 它没有实现接口,而是继承Thread类,并重写了其中的run()方法
3、线程池创建线程
static class DefaultThreadFactory implements ThreadFactory {private static final AtomicInteger poolNumber = new AtomicInteger(1);private final ThreadGroup group;private final AtomicInteger threadNumber = new AtomicInteger(1);private final String namePrefix;DefaultThreadFactory() {SecurityManager s = System.getSecurityManager();group = (s != null) ? s.getThreadGroup() :Thread.currentThread().getThreadGroup();namePrefix = "pool-" +poolNumber.getAndIncrement() +"-thread-";}public Thread newThread(Runnable r) {Thread t = new Thread(group, r,namePrefix + threadNumber.getAndIncrement(),0);if (t.isDaemon())t.setDaemon(false);if (t.getPriority() != Thread.NORM_PRIORITY)t.setPriority(Thread.NORM_PRIORITY);return t;}}
默认是采用DefaultThreadFactory
它会给我们线程池创建的线程设置一些默认的值,比如他的名字,是不是守护线程,以及它的优先级
4、有返回值的Callable
class CallableTask implements Callable<Integer> {@Overridepublic Integer call() throws Exception{return new Random().nextInt();}}//创建线程池ExecutorService service = Executor.newFixedThreadPool(10);// 提交任务 并用Future 提交返回结果Future<Intgeger> future = service.submit(new CallableTask());
-
5、其他创建方式
比如 定时器Timer
TimerTask的实现了Runnable接口,Timer内部有个TimerThread继承自Thread因此绕回来还是Thread
匿名内部类 他不是传入一个已经实例好的runnable对象,而是直接在这边去用一个匿名内部类的方式把需要传入的runnable给实现出来 ``` new Thread(new Runnable(){ @Override public void run() {
System.out.print(Thread.currentThread().getName());
} }).start();
Lambda表达式
new Thread(() -> System.out.print(Thread.currentThread().getName()); ) ```
