java中多线程的创建方式及常用的方法

目录

概述

继承Thread类:

实现Runnable接口:

实现Callable接口:

示例代码

继承Thread类示例

实现Runnable接口示例

实现Callable接口示例

调用三种线程测试示例

线程常用的成员方法


概述

        常见的创建线程的方式包括:继承Thread类、实现Runnable接口和实现Callable接口。

  • 继承Thread类:

    • 这种方式是通过创建一个类,继承自Thread类,并重写其run()方法来定义线程执行的任务。
    • 优点:简单易用,适合简单的线程任务。
    • 缺点:Java不支持多重继承,因此如果继承Thread类,则无法继承其他类。
  • 实现Runnable接口:

    • 这种方式是创建一个类,实现Runnable接口,并实现其run()方法来定义线程执行的任务。
    • 优点:避免了Java单继承的限制,使得代码更加灵活。
    • 缺点:稍微复杂一些,需要创建Thread对象并将实现了Runnable接口的对象作为参数传递给Thread对象。
  • 实现Callable接口:

    • 实现Callable接口,并实现call()方法。call()方法是在新线程中执行的任务,它可以返回一个结果。
    • 返回结果: Callable接口的call()方法可以返回一个结果,而Runnable接口的run()方法是void类型的,无法返回结果。
    • 抛出异常: call()方法可以抛出异常,而run()方法不能。
    • Future对象: Callable接口执行后可以通过Future对象获取结果,而Runnable接口无法获取执行结果。
    • 泛型支持: Callable接口支持泛型,可以指定call()方法的返回类型。

示例代码

继承Thread类示例

public class ThreadTest extends Thread{
    /*
    * 第一种多线程实现方式
    * 继承 Thread 类
    * 然后重写run方法
    * */
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            //循环打印消息,getName方法为当前线程名称
            System.out.println(getName()+"线程运行");
        }
    }
}

实现Runnable接口示例

public class RunnableTest implements Runnable {

    /**
     * 第二种多线程实现方式
     * 此方法是Runnable接口所要求实现的方法,它定义了当线程启动后将要执行的任务逻辑。
     * 在本例中,线程将循环打印100次当前线程的名字和消息"线程运行"。
     */
    @Override
    public void run() {
        // 循环100次
        for (int i = 0; i < 100; i++) {
            // 打印当前线程的名字和消息"线程运行"
            System.out.println(Thread.currentThread().getName() + "线程运行");
        }
    }
}

实现Callable接口示例

/**
 * @author :枫夜
 * @date : 2024-04-22 16:36
 * @description : 本类实现了Callable接口,用于定义一个可被线程执行的任务,并返回计算结果。
 * 本例中,任务计算从0到99的整数之和,并返回结果。
 **/
public class CallableTest implements Callable<Integer> {

    /**
     * 此方法是Callable接口所要求实现的方法,它定义了当线程启动后将要执行的任务逻辑。
     * 在本例中,线程将计算从0到99的整数之和,并返回结果。
     * 使用Callable实现创建的线程,可以获取到线程的返回值
     *
     * @return 计算得到的整数之和
     * @throws Exception 如果在计算过程中发生异常,可抛出Exception以传递给调用者
     */
    @Override
    public Integer call() throws Exception {
        // 初始化累加器
        int sum = 0;

        // 循环计算从0到99的整数之和
        for (int i = 0; i < 100; i++) {
            sum += i;
        }

        // 返回计算结果
        return sum;
    }
}

调用三种线程测试示例

public class Test01 {

    /**
     * 此方法用于展示创建并启动两个自定义线程对象的过程。
     * 它使用TestNG的@Test注解标记为一个测试用例。
     */
    @Test
    public void Test01() {
        // 创建两个ThreadTest实例,分别命名为"线程1"和"线程2"
        ThreadTest threadTest1 = new ThreadTest();
        ThreadTest threadTest2 = new ThreadTest();

        // 设置线程1的名字为"线程1"
        threadTest1.setName("线程1");

        // 设置线程2的名字为"线程2"
        threadTest2.setName("线程2");

        // 启动线程1,使其进入就绪状态并等待CPU调度执行
        threadTest1.start();

        // 启动线程2,使其进入就绪状态并等待CPU调度执行
        threadTest2.start();
    }

    /**
     * 此方法用于展示使用同一个Runnable实例创建并启动两个线程的过程。
     * 它使用TestNG的@Test注解标记为一个测试用例。
     */
    @Test
    public void test02() {
        // 创建一个RunnableTest实例,作为线程共享的任务对象
        RunnableTest runnableTest = new RunnableTest();

        // 使用RunnableTest实例创建线程1
        Thread thread1 = new Thread(runnableTest);

        // 使用RunnableTest实例创建线程2
        Thread thread2 = new Thread(runnableTest);

        // 设置线程1的名字为"线程1"
        thread1.setName("线程1");

        // 设置线程2的名字为"线程2"
        thread2.setName("线程2");

        // 启动线程1,使其进入就绪状态并等待CPU调度执行
        thread1.start();

        // 启动线程2,使其进入就绪状态并等待CPU调度执行
        thread2.start();
    }

    /**
     * 此方法用于展示使用Callable创建一个线程并获取其计算结果的过程。
     * 它使用TestNG的@Test注解标记为一个测试用例,并声明抛出可能发生的ExecutionException和InterruptedException。
     */
    @Test
    public void test03() throws ExecutionException, InterruptedException {
        // 创建一个CallableTest实例,用于计算从0到99的整数之和
        CallableTest callableTest = new CallableTest();

        // 使用CallableTest实例创建一个FutureTask,以便获取计算结果
        FutureTask<Integer> integerFutureTask = new FutureTask<>(callableTest);

        // 创建一个线程来执行FutureTask
        Thread thread = new Thread(integerFutureTask);

        // 启动线程,开始执行Callable任务
        thread.start();

        // 调用FutureTask的get方法,阻塞等待直到计算结果可用,并返回结果
        Integer integer = integerFutureTask.get();

        // 输出计算结果
        System.out.println(integer);
    }
}

线程常用的成员方法

  • String getName()

    • 返回当前线程的名称。
    • 示例:String threadName = Thread.currentThread().getName();
  • void setName(String name)

    • 设置当前线程的名称。
    • 示例:Thread.currentThread().setName("MyThread");
  • static Thread currentThread()

    • 返回当前正在执行的线程对象。
    • 示例:Thread currentThread = Thread.currentThread();
  • static void sleep(long time)

    • 使当前线程休眠指定的时间(以毫秒为单位)。
    • 示例:Thread.sleep(1000);
  • void setPriority(int newPriority)

    • 设置当前线程的优先级,范围为1(最低)到10(最高),默认是5。
    • 示例:Thread.currentThread().setPriority(5);
  • final int getPriority()

    • 返回当前线程的优先级。
    • 示例:int priority = Thread.currentThread().getPriority();
  • final void setDaemon(boolean on)

    • 将当前线程设置为守护线程(Daemon Thread)或用户线程。
    • 守护线程在用户线程结束时自动销毁,销毁不是直接销毁,每次时间不同,但不会时间太长。
    • 示例:Thread.currentThread().setDaemon(true);
  • public static void yield()

    • 暂停当前正在执行的线程对象,并允许其他线程执行。这个方法的作用是让出当前线程的执行权给其他线程,出让之后重新抢夺执行权,谁抢到执行权谁就执行。
    • 示例:Thread.yield();
  • public static void join()

    • 当前线程停止运行,直到被调用的线程执行完毕,然后当前线程再运行。
    • 示例:thread.join();这个示例写在那个线程中,就暂停当前线程,然后运行thread这个线程。
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值