1、继承Thread类
继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。该方法尽管被列为一种多线程实现方式,但是本质上也是实现了 Runnable 接口的一个实例。
public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        //4.创建Thread类的子类对象
        MyThread mt = new MyThread();
        //5.开启线程
        mt.setName("多线程");
        mt.start();
        for(int i = 0; i < 2; i++) {
            System.out.println(Thread.currentThread().getName()  + i);
            // 让线程睡眠一会
            Thread.sleep(10);
        }
    }
}
// 1.继承Thread
class MyThread extends Thread {
    // 2.重写run方法
    @Override
    public void run() {
        //3.将要执行的代码写在run方法中
        for(int i = 0; i < 4; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}
// 通过匿名类创建
public class ThreadTest {
    public static void main(String[] args)  {
        //重写run方法,将要执行的代码写在run方法中
        new Thread(() -> {
            for (int i = 0; i < 4; i++) {
                System.out.println("thread");
            }
        }).start();
    }
}
2、实现Runnable接口
为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下:
public void run()
public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        //4,创建Runnable的子类对象
        MyRunnable mr = new MyRunnable();
        //5,将其当作参数传递给Thread的构造函数
        Thread t = new Thread(mr,"myrunnable");
        t.start();
        for(int i = 0; i < 2; i++) {
            System.out.println(Thread.currentThread().getName()  + i);
            // 让线程睡眠一会
            Thread.sleep(10);
        }
    }
}
//1,定义一个类实现Runnable
class MyRunnable implements Runnable {
    // 2.重写run方法
    @Override
    public void run() {
        //3.将要执行的代码写在run方法中
        for(int i = 0; i < 4; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}
// 内部匿名类
public class ThreadTest {
    public static void main(String[] args)  {
        //1,将Runnable的子类对象传递给Thread的构造方法
        new Thread(new Runnable() {
            @Override
            //2,重写run方法
            public void run() {
                //3,将要执行的代码写在run方法中
                for(int i = 0; i < 4; i++) {
                    System.out.println(Thread.currentThread().getName()+i);
                }
            }//4,开启线程
        }).start();
    }
}
3、通过 Callable 和 Future 创建线程
- 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
- 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
- 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
- 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
public class ThreadTest {
    public static void main(String[] args) throws Exception{
        MyCallable mc = new MyCallable(100);
        FutureTask<Integer> f = new FutureTask<>(mc);
        new Thread(f).start();
        System.out.println(f.get());
    }
}
class MyCallable implements Callable<Integer> {
    private int number;
    //实现从1加到100并返回结果
    public MyCallable(int number) {
        this.number = number;
    }
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int x = 1; x <= number; x++) {
            sum += x;
        }
        return sum;
    }
}
4、创建线程的三种方法对比
- 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。
- 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。
5、线程池
Java中创建和销毁一个线程是比较昂贵的操作,需要系统调用。频繁创建和销毁线程会影响系统性能。于是线程池应运而生。其好处是可以抛出异常和有返回值。
- 创建线程池对象
- 创建Runnable实例
- 提交Runnable实例
- 关闭线程池
// 提交Runnable
public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService pool = Executors.newFixedThreadPool(2);
        // 可以执行Runnable对象或者Callable对象代表的线程
        pool.submit(new MyRunnable());
        pool.submit(new MyRunnable());
        //结束线程池
        pool.shutdown();
    }
}
//1,定义一个类实现Runnable
class MyRunnable implements Runnable {
    // 2.重写run方法
    @Override
    public void run() {
        //3.将要执行的代码写在run方法中
        for(int i = 0; i < 4; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}
//提交Callable
public class ThreadTest {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // 创建线程池对象
        ExecutorService pool = Executors.newFixedThreadPool(2);
        // 可以执行Runnable对象或者Callable对象代表的线程
        Future<Integer> f1 = pool.submit(new MyCallable(100));
        Future<Integer> f2 = pool.submit(new MyCallable(200));
        // V get()
        Integer i1 = f1.get();
        Integer i2 = f2.get();
        System.out.println(i1);
        System.out.println(i2);
        // 结束
        pool.shutdown();
    }
}
class MyCallable implements Callable<Integer> {
    private int number;
    //实现从1加到100并返回结果
    public MyCallable(int number) {
        this.number = number;
    }
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int x = 1; x <= number; x++) {
            sum += x;
        }
        return sum;
    }
}
参考文章:
https://www.runoob.com/java/java-multithreading.html
https://blog.csdn.net/qq_40298054/article/details/87870297
 
                   
                   
                   
                   
                             本文介绍了Java中创建多线程的三种主要方法:继承Thread类、实现Runnable接口及使用Callable与Future。对比了它们之间的优缺点,并展示了如何利用线程池来提高效率。
本文介绍了Java中创建多线程的三种主要方法:继承Thread类、实现Runnable接口及使用Callable与Future。对比了它们之间的优缺点,并展示了如何利用线程池来提高效率。
           
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   1444
					1444
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            