Java创建线程的方法(Java创建线程的四种方法)

Java创建线程的方法(Java创建线程的四种方法),第1张

Java创建线程的方法(Java创建线程的四种方法)

很多学习Java基础的小伙伴肯定听说过多线程。那么我们有几种方式来创建线程呢?在jdk1.5或者jdk5之前有两种方式,一种是继承Thread类,另一种是实现Runnable接口。在jdk1.5后又为我们提供两种方式,一种是实现Callable接口,另一种就是使用线程池。下面我们来简单的说一下四种方式是如何创建线程的。

一、继承Thread类。

继承Thread类需要我们重写run()方法,且将核心代码写到run方法中。这里我们在创建的线程中打印1到100以内的偶数为例。代码如下:

package com.aoshen.java2;


//首先我们需要继承Thread类
class NumTest extends Thread {
    //    重写Thread类的run方法
    @Override
    public void run() {
//        将核心代码写到run方法里面
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0) {
                System.out.println(i);
            }
        }
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        NumTest numTest=new NumTest();
//        numTest.setName("线程名"); 这里是给线程起一个名字
//        启动线程并调用run方法
        numTest.start();

//        numTest.start();这里是错误的,对于继承的方式来讲,如果我们对已经start过的线程再调用start就会出错
//        正确的方式是如下方式,也就是需要我们重新创建一个对象来调用
//        NumTest numTest1=new NumTest();
//        numTest1.start();
    }
}

二、实现Runnable接口,同样是打印1到100以内的偶数为例:

package com.aoshen.java2;



//实现Runnable接口
class NumTest1 implements Runnable {
    //    重写run方法,并将核心代码写到run方法中
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0) {
                System.out.println(i);
            }
        }
    }
}

public class RunnableTest {
    public static void main(String[] args) {
//        创建对象
        NumTest1 numTest = new NumTest1();
//        创建Thread并将上步的对象作为参数传入构造器
        Thread thread = new Thread(numTest);
//        thread.setName("线程名");
//        启动线程
        thread.start();

//        如果想再次执行的话,这种实现的方式只需要我们按照如下方式
//        再创建一个Thread对象,将实现类的想传入构造器,并调用
//        Thread对象的start即可
//        Thread thread1=new Thread(numTest);
//        thread1.start();
    }
}

三、实现Callable接口

通过上面的两个例子我们可以看出,不管是继承Thread类还是实现Runnable接口,其核心就是重写run方法,但是run方法的返回值是void也就是说没有返回值。而且run方法是不能抛出异常的,如果我们的业务复杂一下的话,需要捕获异常的话是捕获不到的。那么实现Callable接口的方式可以在我们重新call方法的时候抛出异常,也可以有返回值。比如,我们需要打印1到100以内的偶数,并需要返回偶数的和为例。

package com.aoshen.java2;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;


//实现Callable接口,Callable接口是有泛型的,这个
//泛型就是我们我们调用call方法所需要返回的值的类型
class NumTest2 implements Callable {

    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
//            遍历1到100以内的所有偶数,并将所有偶数的和返回
            if (i % 2 == 0) {
                System.out.println(i);
                sum += i;
            }
        }
        return sum;
    }
}

public class CallableTest {
    public static void main(String[] args) {
//        创建NumTest2对象
        NumTest2 numTest2 = new NumTest2();
//        创建FutureTask对象 并将上步的对象作为参数传入
        FutureTask futureTask = new FutureTask<>(numTest2);
//        创建Thread类,并将上步对象传入
        Thread thread = new Thread(futureTask);
//启动线程
        thread.start();

        try {
//           获取线程执行后返回的返回值,这一步不是必须的,如果你不需要返回值,则这一步可以不写 
            Integer integer = futureTask.get();
            System.out.println("总和为:" + integer);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

四、使用线程池

使用线程池的好处有以下几点

1.提高效率,不用重复的创建和销毁线程

2.提高利用率

3.可以对线程池进行一些设置

package com.aoshen.java2;

import java.util.concurrent.*;


//实现遍历1到100以内的偶数
class RunnableDemo implements Runnable {
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0) {
                System.out.println(i);
            }
        }
    }
}

//实现遍历 1到100以内的奇数,并将奇数的和返回
class CallableDemo implements Callable {

    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
//            遍历1到100以内的所有偶数,并将所有偶数的和返回
            if (i % 2 != 0) {
                System.out.println(i);
                sum += i;
            }
        }
        return sum;
    }
}


public class ThreadPollTest {
    public static void main(String[] args) {
//        创建固定线程数量的线程池
        ExecutorService service = Executors.newFixedThreadPool(5);
        RunnableDemo runnableDemo = new RunnableDemo();
//        如果是实现Runnable接口的方式则调用execute方式来执行
        service.execute(runnableDemo);

        CallableDemo callableDemo = new CallableDemo();
//        如果是实现Callable接口的方式则调用submit方式来执行
        Future future = service.submit(callableDemo);
        try {
            Integer integer = future.get();
            System.out.println("和为:" + integer);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
//        最后要记得关闭线程池哦
        service.shutdown();
    }

}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5703593.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存