首页 > 编程语言 >JAVA多线程(一)--实现/创建方式

JAVA多线程(一)--实现/创建方式

时间:2023-02-12 15:00:27浏览次数:50  
标签:Runnable JAVA Thread -- void 线程 run 多线程 public

JAVA多线程(一)--实现/创建方式

一、继承Thread类

Thread类本质上是一个实现了Runnable接口的实例,代表一个线程的实例。启动线程的唯一方法是调用Thread类的start()方法,start()方法中调用了一个native方法start0(),它将启动一个线程,并执行run()方法。

//部分Thread源码
public class Thread implements Runnable {
    //......
    public synchronized void start() {

        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    // 本地方法,使用c代码初始化线程,并运行run()方法
    private native void start0();

    @Override
    public void run() {
        if (target != null) {
            //这里的target是一个Runnable接口实现的引用
            target.run();
        }
    }
    // .....
}

代码:

// 继承Thread类
public class MyThread extends Thread{
    @Override
    public void run(){
        System.out.println("MyThread running");
    }

    public static void main(String[] arg){
	//创建线程并运行
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

二、实现Runnable接口

如果类已经继承了一个类,就无法再继承Thread类,此时可以实现一个Runnable接口。

// Runnable源码
@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

使用Runnable接口实现线程类时,为了启动线程,需要用该类初始化一个Thread类对象。

// 实现代码
public class MyThread1 extends MyThread implements Runnable{
    @Override
    public void run(){
        System.out.println("MyThread1 running");
    }

    public static void main(String[] arg){
        MyThread1 myThread1 = new MyThread1();
        Thread thread = new Thread(myThread1);
        thread.start();
    }
}

三、实现Callable接口

无返回值的任务实现Runnable接口,而有返回值的任务就需要实现Callable接口。
执行Callable任务后,返回一个Future对象。在该对象上调用get()方法就可以得到Callable任务返回的对象。使用Callable需要结合ExecutorService线程池接口。

// Callable源码
@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}
// 实现代码:
public class MyCallableThread implements Callable<String> {

    private final String name;
    MyCallableThread(String name){
        this.name = name;
    }
    @Override
    public String call(){
        return this.name;
    }

    public static void main(String[] arg) throws ExecutionException, InterruptedException {
        int size = 5;
        ExecutorService pool = Executors.newFixedThreadPool(size);
        List<Future<String>> futures = new ArrayList<>();
        for(int i=0;i<size;i++){
            Future<String> future = pool.submit(new MyCallableThread(i+""));
            futures.add(future);
        }
        pool.shutdown();
        for (Future<String> future : futures){
            System.out.println("res: "+ future.get());
        }
    }
}
   /**
     * 执行结果:
     * res: 0
     * res: 1
     * res: 2
     * res: 3
     * res: 4
     */

四、基于线程池

每次创建线程都要为线程分配堆栈内存以及初始化内存,还需要进行系统调用。频繁的创建和销毁线程会大大降低系统运行效率,非常浪费资源。可以使用缓存的策略,也就是线程池来实现多线程。
详情:JAVA多线程(二)--线程池

标签:Runnable,JAVA,Thread,--,void,线程,run,多线程,public
From: https://www.cnblogs.com/code-tong/p/17111516.html

相关文章

  • C语言填空:回文字符串
    #include<stdio.h>//输入一个字符串(20个字符以内),判断其是否是回文字符串(回文字符串是指正反一样的字符串)。【1】main(){chara[21];intb,【2】,len;......
  • MySQL——优化(二):索引创建和失效
    一、创建索引的原则1、建议创建索引的场景where语句的查询条件select语句,对于某些字段经常作为where语句的查询条件;Update/delete语句的where条件频繁使用时......
  • Ribbon负载均衡 (源码分析)
    Ribbon负载均衡SpringCloud已经删除了ribbon组件,所以需要手动导入依赖。(要学是因为很多项目业务已经使用了ribbon)服务拉取的时候添加了@LoadBalanced注解,实现负载均衡......
  • C++ | 引用
    01.引用概述1.1创建引用变量引用是已定义的变量的别名(另一个名称)。inta;int&b=a;//将b作为a变量的别名C和C++使用&符号来指示变量的地址。C++给&符号赋予了另......
  • StampedLock源码解析
    StampedLock源码解析StampedLock描述一种基于能力的锁,具有三种模式,用于控制读写访问。StampedLock的状态由版本和模式组成。锁获取方法返回一个表示并控制对锁状态访问......
  • AtCoder Beginner Contest 289
    A-flip(abc289a)题目大意给定一个\(01\)字符串,翻转\(01\)输出解题思路模拟即可神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlo......
  • 网站开启https可以使用免费SSL证书吗?需要根据具体场景选择
    被问到安装SSL证书能否使用市面上的一些免费版,答案当然是没有问题的,可以使用。实话实说,目前大多是个人的项目或者博客网站,基本前期都是使用的免费版SSL证书。当形成一定规......
  • 华科日寄 2nd Season
    大一下半学期,新学期开新坑用上目录功能可以方便快速查看哦持续更新中……大概吧……2.11坐高铁回学校,然而下了高铁后不幸赶上晚高峰。本来想打车结果发现高铁站排队打......
  • Python----基础知识测试
    一、单选题(每题2分)1、列标识符命名中,符合规范的是()A、1aB、forC、_123D、#_b2、下列标识符中,不是Python支持的数据类型的是()A、charB、intC、floatD、str3、下......
  • break 测试
    packagecom.zxs.process;importjavax.jws.soap.SOAPBinding;publicclassbreakces{publicstaticvoidmain(String[]args){inti=0;while(......