首先我们来复习我们学习 java 时接触的线程创建,这也是面试的时候喜欢问的,有人说两种也有人说三种四种等等,其实我们不能去死记硬背,而应该深入理解其中的原理,当我们理解后就会发现所谓的创建线程实质都是一样的,在我们面试的过程中如果我们能从本质出发回答这样的问题,那么相信一定是个加分项!好了我们不多说了,开始今天的 code 之路
**
这是我们最常见的创建线程的方式,通过继承 Thread 类来重写 run 方法,
代码如下:
测试方法:
@Test public void thread01(){ Thread thread = new ThreadDemo(); thread.setName("线程-1 "); thread.start(); while (true){ System.out.println("这是main主线程:" + Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }结果:
继承 Thread 的线程创建简单,启动时直接调用 start 方法,而不是直接调用 run 方法。直接调用 run 等于调用普通方法,并不是启动线程
1.2 **实现 Runnable 接口创建线程 ****
上述方式我们是通过继承来实现的,那么在 java 中提供了 Runnable 接口,我们可以直接实现该接口,实现其中的 run 方法,这种方式可扩展性更高
代码如下:
测试代码:
@Test public void runnableTest(){ // 本质还是 Thread ,这里直接 new Thread 类,传入 Runnable 实现类 Thread thread = new Thread(new RunnableDemo(),"runnable子线程 - 1"); //启动线程 thread.start(); while (true){ System.out.println("这是main主线程:" + Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }运行结果:
1.3 实现 Callable 接口创建线程
这种方式是通过 实现 Callable 接口,实现其中的 call 方法来实现线程,但是这种线程创建的方式是依赖于 ** **FutureTask **包装器**来创建 Thread , 具体来看代码
代码如下:
测试代码:
@Test public void callable() throws ExecutionException, InterruptedException { //创建线程池 ExecutorService service = Executors.newFixedThreadPool(1); //传入Callable实现同时启动线程 Future submit = service.submit(new CallableDemo()); //获取线程内容的返回值,便于后续逻辑 System.out.println(submit.get()); //关闭线程池 service.shutdown(); //主线程 System.out.println("这是main主线程:" + Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } }结果: