java创建多线程的7种方式---代码详解

一、继承Thread类

1.代码示例

public class Thread01 extends Thread {
    
    
    // 线程执行的代码在run()方法中,执行完毕后,线程死亡
    @Override
    public void run() {
    
    
        System.out.println(Thread.currentThread().getName() + "<我是子线程>");
        try {
    
    
            Thread.sleep(3000);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "子线程执行完毕");
    }

    public static void main(String[] args) {
    
    
        System.out.println(Thread.currentThread().getName() + "我是主线程");
        //启动线程调用start()方法而不是run()方法 调用start()后线程变为就绪状态,而不是运行状态,还需等待CPU调度运行
        new Thread01().start();
        new Thread01().start();
        System.out.println("---主线程执行完毕---");
    }
}

运行结果如下:

main我是主线程
---主线程执行完毕---
Thread-0<我是子线程>
Thread-1<我是子线程>
Thread-1子线程执行完毕
Thread-0子线程执行完毕

2.总结

可以看出,主线程是不需要等待子线程执行完再执行下面的程序,主线程执行完了子线程还在执行,因此,子线程报错是不会影响主线程的。

二、实现runable接口

1.代码示例

public class Thread02 implements Runnable{
    
    

    @Override
    public void run() {
    
    
        System.out.println(Thread.currentThread().getName() + "<我是子线程>");
    }

    public static void main(String[] args) {
    
    
        System.out.println("主程序运行");
        new Thread(new Thread02()).start();
        new Thread(new Thread02()).start();
        System.out.println("主程序运行结束---");
    }
}

运行结果:

主程序运行
主程序运行结束---
Thread-0<我是子线程>
Thread-1<我是子线程>

三、使用匿名内部类

public class Thread02 implements Runnable{
    
    

    @Override
    public void run() {
    
    
        System.out.println(Thread.currentThread().getName() + "<我是子线程>");
    }

    public static void main(String[] args) {
    
    
        System.out.println("主程序运行");
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(Thread.currentThread().getName() + "<我是子线程>");
            }
        }).start();
        System.out.println("主程序运行结束---");
    }
}

运行结果:

主程序运行
主程序运行结束---
Thread-0<我是子线程>

四、使用lambda表达式

public class Thread02 implements Runnable{
    
    

    @Override
    public void run() {
    
    
        System.out.println(Thread.currentThread().getName() + "<我是子线程>");
    }

    public static void main(String[] args) {
    
    
        System.out.println("主程序运行");
        new Thread(() -> System.out.println(Thread.currentThread().getName() + "<我是子线程>")).start();
        System.out.println("主程序运行结束---");
    }
}

运行结果:

主程序运行
主程序运行结束---
Thread-0<我是子线程>

五、使用callable和Future创建

1.简介

callable和future现成可以获取到返回的结果,底层是基于LockSupport,从JDK5就提供了Callable接口,该接口是Runable的增强版

2.代码实现

public class ThreadCallable implements Callable<Integer> {
    
    
    /**
     * 当前线程需要执行的代码,以及返回结果
     * @return
     * @throws Exception
     */
    @Override
    public Integer call() throws Exception {
    
    
        System.out.println("子线程开始执行。。");
        try {
    
    
            Thread.sleep(3000);
        } catch (Exception e) {
    
    

        }
        System.out.println(Thread.currentThread().getName()+":返回1");
        return 1;
    }
}
public class Thread03  {
    
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        ThreadCallable threadCallable = new ThreadCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(threadCallable);
        new Thread(futureTask).start();
        Integer result = futureTask.get();
        System.out.println(Thread.currentThread().getName()+","+result);
    }

}

运行结果如下:

子线程开始执行。。
Thread-0:返回1
main,1

3.注意

futureTask能返回线程的结果其实在调用get()方法时,底层的LockSupport调用LockSupport.park()方法,使主线程挂起等待,等子线程运行完返回结果后,再由LockSupport.unpark()唤起主线程。在子线程未返回结果前,主线程是阻塞等待状态的。

六、使用线程池例如Executor框架创建

public class Thread04 {
    
    
    public static void main(String[] args) {
    
    
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(() -> System.out.println("我是子线程"));
    }
}

七、spring @Async异步注解

只需要在调用的方法上写上注释@Async即可,被@Async注释的方式是异步执行的,相当于主线程中会单独另起一个线程执行。

猜你喜欢

转载自blog.csdn.net/m0_37899908/article/details/131995064