多线程的实现方式

多线程的实现方式

1、继承Thread类

   (1)定义一个类继承Thread,重写run()方法;
   (2)创建Thread类的子类对象;
   (3)调用start()开启新线程。

//主线程和自定义线程并发执行
public class thread {
    public static void main(String[] args) {
    	//2、创建Thread类的子类对象
        MyThread myThread = new MyThread();     
        //3、调用start()开启新线程
        myThread.start();                       

        for (int i = 0; i < 3000; i++) {
            System.out.println("bb");
        }
    }
}

//1、定义一个类继承Thread,重写run()方法
class MyThread extends Thread{              
    public void run(){                      
        for (int i = 0; i < 3000; i++) {    
            System.out.println("aaaaa");
        }
    }
}

2、实现Runnable接口

   (1)定义类实现Runnable接口,重写run()方法;
   (2)创建自定义的Runnable的子类对象;
   (3)创建Thread对象,将Runnable当做参数传递给Thread的构造函数;
   (4)调用start()开启新线程。

//主线程和自定义线程并发执行
public class thread {
    public static void main(String[] args) {
    	//2、创建自定义的Runnable的子类对象
        MyRunnable myRunnable = new MyRunnable();   
		//3、创建Thread对象,将Runnable当做参数传递给Thread的构造函数
        Thread thread = new Thread(myRunnable);     
        //4、调用start()开启新线程
        thread.start();                             

        for (int i = 0; i < 3000; i++) {
            System.out.println("bb");
        }
    }
}

//1、定义类实现Runnable接口,重写run()方法
class MyRunnable implements Runnable {      
    @Override                               
    public void run() {
        for (int i = 0; i < 3000; i++) {   
            System.out.println("aaaaa");
        }
    }
}

3、实现Callable接口

   (1)定义类实现Callable接口,重写call()方法;
   (2)创建Callable子类的实例化对象;
   (3)创建FutureTask对象,并将Callable对象传入FutureTask的构造方法中;
   (4)实例化Thread对象,并在构造方法中传入FutureTask对象;
   (5)调用start()启动新线程。

//主线程和自定义线程并发执行
public class thread {
    public static void main(String[] args) {
        //2、创建Callable子类的实例化对象
        MyCallable myCallable = new MyCallable();
        //3、创建FutureTask对象,并将Callable对象传入FutureTask的构造方法中
        FutureTask futureTask = new FutureTask<String>(myCallable);
        //4、实例化Thread对象,并在构造方法中传入FutureTask对象
        Thread thread = new Thread(futureTask);
        //5、调用start()启动新线程
        thread.start();
        
        for (int i = 0; i < 3000; i++) {
            System.out.println("bb");
        }
    }
}

//1、定义类实现Callable接口,重写call()方法
class MyCallable implements Callable{
    @Override
    public String call() throws Exception {
        for (int i = 0; i < 3000; i++) {
            System.out.println("aaaaaaaa");
        }
        return "0";
    }
}

4、第1种,第2种和第3种的匿名内部类

5、基于线程池的方式

  我们知道,线程和数据库连接这些资源都是非常宝贵的资源。那么每次需要的时候创建,不需要的时候销毁,是非常浪费资源的。那么我们就可以使用缓存的策略,也就是使用线程池。当然了,线程池也不需要我们来实现,jdk的官方也给我们提供了API。

public class CreateThreadDemo12_ThreadPool {
    public static void main(String[] args) throws Exception {
        // 创建固定大小的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);

        while (true) {
            // 提交多个线程任务,并执行
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    printThreadInfo();
                }
            });
        }
    }

    /**
     * 输出当前线程的信息
     */
    private static void printThreadInfo() {
        System.out.println("当前运行的线程名为: " + Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

  输出结果为:

当前运行的线程名为: pool-1-thread-1
当前运行的线程名为: pool-1-thread-2
当前运行的线程名为: pool-1-thread-4
当前运行的线程名为: pool-1-thread-3
当前运行的线程名为: pool-1-thread-7
当前运行的线程名为: pool-1-thread-8
当前运行的线程名为: pool-1-thread-9
当前运行的线程名为: pool-1-thread-6
当前运行的线程名为: pool-1-thread-5
当前运行的线程名为: pool-1-thread-10

继承Thread类和实现Runnable接口这两种方式的区别:

  1、实现Runnable接口,可以避免单继承的局限性,具有较强的健壮性。
  2、Runnable可以实现资源的共享,多个线程同时处理同一资源。
  3、Thread类的线程间都是独立运行的,资源不共享。
  4、继承Thread类不再被其他类继承。

实现Runnable接口和实现Callable接口这两种方式的区别:

  1、Callable的核心是call()方法,允许返回值;Runnable的核心是run()方法,没有返回值。
  2、call()方法可以抛出异常,但是run()方法不行。
  3、Callable和Runnable都可以应用于executor是,而Thread类只支持Runnable。

上一篇:7_Callable&Future接口


下一篇:(八)深入并发之Runnable、Callable、FutureTask及CompletableFuture原理分析