问题一:创建线程的方法有很多种?刚开始学习Java多线程编程的时候,被告知创建线程有两种方式:继承Thread类,重写run方法,如例1;实现Runnable接口,如示例2所示;例1:继承Thread类:classMyThreadextendsThread{@Overridepublicvoidrun(){System.out.println(Thread.currentThread());}publicstaticvoidmain(String[]args){MyThreadt=newMyThread();t.开始();}}示例2:实现Runnable接口:publicstaticvoidmain(String[]args){Runnabler=()->{System.out.println(Thread.currentThread());};线程t=新线程(r);t.开始();但是,仔细观察会发现,即使实现了Runnable接口,仍然需要丢到Thread中。所谓Runnable接口的实现只是定义了线程的工作内容。也许你听说过Callable接口,这里有一种写法:staticclassMCallimplementsCallable{@OverridepublicStringcall(){return"hello";}}publicstaticvoidmain(String[]args){Callablecallable=newMCall();FutureTasktask=newFutureTask<>(callable);线程t=新线程(任务);t.开始();看,仍然需要创建Thread对象。不管你用什么tricks,最后都得老老实实的创建一个Thread或者它的子类的实例。线程是创建线程的唯一方法。线程池中的线程仍然是Thread实例。问题2:newThread()是否创建线程?在Threadt=newThread();下面创建了一个Thread实例;此时,我们只得到了一个Thread对象,还没有创建线程。这个说法可能会让你大吃一惊。我们先来看一个例子。staticclassMThreadextendsThread{@Overridepublicvoidrun(){//打印当前线程名System.out.println(Thread.currentThread().getName());}}publicstaticvoidmain(String[]args){MThreadthread=newMThread();线程.run();//注意这里调用了run方法}猜猜打印的结果是什么?结果-main还记得我们刚学java的时候,老师告诉我们要调用start而不是run。两者有什么区别?答案是start方法内部调用本地方法start0,实际上是触发操作系统创建一个线程(内核线程),然后jvm调用run方法在新线程上运行。如果直接调用run,和普通方法一样,不会创建线程,run方法仍然在当前线程中运行,所以上面运行的结果是main。小结通过本文,我们知道:在java中,创建线程必须通过创建Thread或其子类的实例并调用start方法来实现;启动和运行的区别。