首页 > 其他分享 >【Thread -- 1.1】 实现多线程的正确姿势

【Thread -- 1.1】 实现多线程的正确姿势

时间:2023-03-21 21:55:23浏览次数:49  
标签:Runnable run 1.1 Thread void 线程 多线程 public

【Thread -- 1.1】 实现多线程的正确姿势

一、实现多线程的方法有几种--两种

1、正确方法--Oraclle官方文档--2种

[Oraclle官方文档](Overview (Java Platform SE 8 ) (oracle.com))

  • 实现Runnable接口--推荐,优点:

    • 代码架构解耦,将具体运行内容和创建线程解耦
    • 资源节约 不用每次都创建新线程
    • 扩展性 接口能多继承
  • 继承Thread类(重写Runnable的run方法)

2.、承Thread

package Thread.createthreads;

/**
 * 描述:     继承Thread方式实现线程
 */
public class ThreadStyle extends Thread{

    @Override
    public void run() {
        System.out.println("用Thread类实现线程");
    }

    public static void main(String[] args) {
        new ThreadStyle().start();
    }
}


源码分析:

image-20230321212927278

image-20230321213006161

3、实现Runnable接口

package Thread.createthreads;

/**
 * 描述:     用实现Runnable接口创建线程
 * 优点:      代码架构解耦,将具体运行内容和创建线程解耦
 *             资源节约   不用每次都创建新线程
 *             扩展性   接口能多继承
 */
public class RunnableStyle{

    public static void main(String[] args) {
        Thread thread1 = new Thread(new test1());
        Thread thread2 = new Thread(new test2());

        thread2.start();
        thread1.start();
    }
}


class test1 implements  Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ":");
            System.out.println(i);
        }
    }
}
class test2 implements  Runnable{
    @Override
    public void run() {
        for (int i = 10; i < 20; i++) {
            System.out.println(Thread.currentThread().getName() + ":");
            System.out.println(i);
        }
    }
}

源码分析

image-20230321213047127

4、两者比较

run方法:线程中逻辑主要方法。

Runnbale接口:只有一个run方法,即实现run方法。

Thread类:继承了Runnable方法,需要重写run方法。

-----两者都是对run方法进行重写,其实都是Thread类对run进行调用。

/**
 * 描述:同时使用两种方法实现线程的方式
 */
public class BothRunnableThread {

    public static void main(String[] args) {
        //匿名内部类
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我来自Runnable");
            }
        }) {
            //覆盖了Thread中的run方法
            @Override
            public void run() {
                System.out.println("我来自Thread");
            }
        }.start();
    }
}

img

结果解释:创建Thread类时,重写了run方法,不会在对target(Runnable)的代码进行执行了。

5、结论

总的来说,线程只有一种创建方式,就是构造Thread类,但是Thread类中的执行方法run有两种构建方式:

  • 实现Runnable接口的run方法,并且将实现Runnable的实例传给Thread类
  • 继承Thread后重写run方法

二、典型的错误创建观点

1、“线程池”

package Thread.createthreads.wrongs;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池创建
 * 实际上也是new Thread( Runnable)
 */
public class ThreadPool {


    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 100; i++) {
            executorService.submit(new Task());
        }

    }

}


class Task implements  Runnable{

    @Override
    public void run() {
        try {
            //休眠
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印线程名字
        System.out.println(Thread.currentThread().getName());
    }
}

image-20230321214234190

实际上也是new Thread 通过Runnable实现。

2、通过Callable和FutureTask创建线程,也算是一种新建线程的方式

实现图,FutureTask也是由Runnable和Thread实现的

img

img

3、通过定时器创建也是一种方法

/**
 * 描述:定时器创建线程
 * 每隔一秒打印当前线程的名字
 */
public class DemoTimmerTask {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        }, 1000, 1000);
    }
}

4、匿名内部类实现线程的创建也是一种方法

public class AnonymousInnerClassDemo {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        }.start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        }).start();
    }
}

三、Lambad表达式

package Lambad;

@FunctionalInterface
public interface MyFun {
    public abstract Integer getValue(Integer i);
}

package Lambad;

import java.util.Comparator;
import java.util.function.Consumer;

/**
 * Lambad 基础语法 :     新操作符" -> "
 *
 * 左侧:参数列表
 * 右侧:执行功能(体)
 *
 * 语法格式一:无参数,无返回值
 *             () -> do
 *
 * 语法格式二:一个参数,无返回值
 *              (x) -> do  一个参数()可去掉
 *
 *语法格式三: 两个参数,有返回值 且体中有多条语句
 *        Comparator<Integer> com = (x, y) -> {
 *             System.out.println("函数式接口");
 *             return Integer.compare(x,y);
 *         };
 *
 *
 * Lambad需要“函数式接口”的支持 ,@FunctionalInterface可以检测是否是函数式接口。
 *          一个抽象方法
 */

public class Demo01 {
    public static void main(String[] args) {
        new Demo01().test1();
        new Demo01().test2();
        A.say();


    }
    //格式一
    public void test1(){
        int a = 0;//final
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("one");
            }
        };
        runnable.run();

        Runnable lam_runnable = () -> System.out.println("one" + a);
        lam_runnable.run();
    }

    //格式二
    public void test2() {
        Consumer<String> con = (x) -> System.out.println(x) ;
        con.accept("two");
    }


    //格式三
    public void test3(){
        Comparator<Integer> com = (x, y) -> Integer.compare(x,y);

    }


}



interface A{
     public static void say() {
         System.out.println("A");
     };
}

class B implements A{
    public void say(){
        System.out.println("B");
    }
}

四 、面试常见问题

img

img

  • 代码架构解耦,将具体运行内容和创建线程解耦
  • 资源节约 不用每次都创建新线程
  • 扩展性 接口能多继承

标签:Runnable,run,1.1,Thread,void,线程,多线程,public
From: https://www.cnblogs.com/DAIXUM/p/17241661.html

相关文章

  • fastapi多线程非阻塞启动
    1问题描述我在run.py文件下的主函数如下所示:importuvicornfromfastapiimportFastAPIapp=FastAPI(title="chatglm",description="开源版的chatglm接......
  • flink1.13.0 环境搭建
    #flink部署1.standalone模式2.yarn模式session-cluster模式job-cluster模式3.k8s模式注:yarn模式需要依赖hadoop环境,#1.standalone模式直接下载flink-1.13.0......
  • es5.1.1 修改索引数据
    #环境描述使用es版本为:5.1.1使用client为:TransportClientclient,不是highLevelClient#1.知道当前数据rowid时UpdateRequestupdateRequest=newUpdateRequest("index-2......
  • Java ThreadPoolTaskExecutor 线程池的常见问题
    JavaThreadPoolTaskExecutor线程池的常见问题 https://blog.csdn.net/weixin_43611528/article/details/123083314 重要参数corePoolSize:核心线程数,常开的线程数,默......
  • 离线安装 Nginx 1.18
    离线安装Nginx1.18安装依赖:gcc、gcc-c++、ssl、pcre、zlib。注意:一定要先安装gcc,再安装gcc-c++。然后再安装其他,其他的没有先后顺序。一、安装依赖gcc、gcc-c++等依赖......
  • 【python】多线程并发,rpc接口性能测试
    1、官方文档https://docs.python.org/3/library/concurrent.futures.html 2、安装python3.x中自带了concurrent.futures模块python2.7需要安装futures模块,使用命令......
  • tkinter中使用thread
    importtkinterastkfromthreadingimportThreadimportdatetimeimporttimeclassSampleApp(tk.Tk): def__init__(self): tk.Tk.__init__(self) #Makea......
  • javaSE-day12(多线程)
    1.多线程的常用方法Thread提供了很多与线程操作相关的方法方法:publicvoidrun():线程的任务方法publicvoidstart():启动线程publicStringgetName():获取当前......
  • VirtualBox 5.1.12发布支持Linux Kernel 4.10
    甲骨文(Oracle)近日宣布了VirtualBox5.1稳定版分支最新维护版本更新,带来了大量有价值的BUG修复和系统改善。VirtualBox5.1.12尤其为​​Linux​​用户新增了大量内容,除了支......
  • C++温故补缺(十五):多线程
    多线程参考:CSDN,知乎传统C++(C++11之前)中并没有引入线程的概念,如果想要在C++中实现多线程,需要借助操作系统平台提供的API,如Linux的<pthread.h>,或windows下的<windows.......