Java多线程创建的五种常见方法

1. 继承Thread类

继承Thread并重写run方法,并调用start方法。

public class ThreadDemo extends Thread {
    
    

    @Override
    public void run() {
    
    
        while (true) {
    
    
            System.out.println(Thread.currentThread().getName() + " is running ... "); // 打印当前线程的名字 
        }
    }

    public static void main(String[] args) {
    
    
        ThreadDemo td = new ThreadDemo();
        td.start(); // 启动线程
    }
}

2. 实现Runnable接口

实现Runnable接口,并用其初始化Thread,然后创建Thread实例,并调用start方法。

public class ThreadTarget implements Runnable {
    
    
    @Override
    public void run() {
    
    
                System.out.println(Thread.currentThread().getName() + " is running .. "); 

    }
}
//----------------分割线

public class Main {
    
    

    public static void main(String[] args) {
    
    

        ThreadTarget tt = new ThreadTarget(); // 实例化线程任务类
        Thread t = new Thread(tt); // 创建线程对象,并将线程任务类作为构造方法参数传入
        t.start(); // 启动线程
    }
}

3. 定时器

定时器可以说是一种基于线程的一个工具类。可以定时的来执行某个任务。

例如:在2020年3月19日晚上10点执行任务。

public class TimerDemo {
    
    

    private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    public static void main(String[] args) throws Exception {
    
    
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("定时任务执行了....");
            }
        }, format.parse("2020-3-19 22:00:00"));
    }
}

4. 继承Callable接口

继承Thread类还是实现Runnable接口的方法有两个问题,第一个是无法抛出更多的异常,第二个是线程执行完毕之后并无法获得线程的返回值。

实现Callable的方法可以爬出异常,也可以带返回值。

  1. 创建一个类实现Callable接口,实现call方法。这个接口类似于Runnable接口,但比Runnable接口更加强大,增加了异常和返回值。
  2. 创建一个FutureTask,指定Callable对象,做为线程任务。
  3. 创建线程,指定线程任务。
  4. 启动线程

代码如下:

public class CallableTest {
    
    

    public static void main(String[] args) throws Exception {
    
    
        Callable<Integer> call = new Callable<Integer>() {
    
    
    //这里使用匿名内部类的方式来重写call()方法
            @Override
            public Integer call() throws Exception {
    
    
                System.out.println("thread start .. ");
                Thread.sleep(2000);
                return 1;
            }
        };
    //创建一个FutureTask,指定Callable对象,做为线程任务。
        FutureTask<Integer> task = new FutureTask<Integer>(call);
        Thread t =  new Thread(task);

        t.start();
        task.get();//获取返回值,get是个阻塞方法,只有获取到返回值才会放行线程
        System.out.println("do other thing .. ");
        System.out.println("拿到线程的执行结果 : " + task.get());
    }

}

5. 基于线程池的方法

public class ThreadPoolDemo {
    
    

    public static void main(String[] args) {
    
    

        // 创建线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);//最多可以有10个线程

        while(true) {
    
    
            threadPool.execute(new Runnable() {
    
     // 提交多个线程任务,并执行(匿名内部类的方式)

                @Override
                public void run() {
    
    
                    System.out.println(Thread.currentThread().getName() + " is running ..");
                    try {
    
    
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
            });
        }
    }

}

最后

内容摘自:https://www.nowcoder.com/questionTerminal/8f4a97a1101148cab4efa69bd67e5ac3

原作者主页:https://www.nowcoder.com/profile/165701207?noredirect=true

扫描二维码关注公众号,回复: 12732514 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_44491553/article/details/113811755