Java 多线程

本篇主要介绍一下在 Java 语言中,对于多线程的理解、使用与总结。

一 简介

通常线程的概念可以这样理解:

1 客户端----> 服务端;

2 客户端发起一个请求,服务端会启动一个线程去处理这个请求,这个线程先称为主线程;

3 多个客户端发起请求时,服务端会针对每个客户端的请求启动一个线程,去处理;

4 服务端启动的这个主线程,会顺序处理相应的业务逻辑;(主要讲述一下这个阶段)

.......

如图所示:

主线程在处理业务逻辑时,是按照顺序执行的。像图中所示,整个主线程的处理时间是 4秒。这样的请求时间,简直不能忍受。

想想我们现实中的业务场景:

1 BS客户端请求数据;

2 SS服务间的调用;

这个时候我们可以使用多线程去处理这样的问题,处理方案:

1 启用多个子线程同时处理,合并每个子线程的处理结果;

例如上图场景,启动三个子线程,子线程 1处理任务1,子线程 2处理任务2,子线程 3处理任务3,每个子线程处理完后,都把处理结果添加到结果集中;

并行处理应根据具体的业务场景实现;

2 主线程只做接收参数处理,异步线程处理业务逻辑,完成后采用其他形式通知请求方;

例如上图场景,先做接收成功xiang响应;启动一个异步线程,去处理业务逻辑 任务1、任务2、任务3,处理完成后,通知客户端处理结果、或者根据标识让客户端来取结果等。

二 多线程实现方式

实现子线程或异步线程的方式通常有三种:实现Runnable接口,继承Thread类,实现Callable接口;

1 继承 Thread 类

该方式 无返回值,但是可以通过共现结果变量、标记的形式实现;

样例:

package com.study.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;
import java.util.List;

/**
 * 继承 thread 类的方式实现多线程
 * @auth zhangmj
 * @date 2019/2/11 14:45
 */
@Slf4j
public class ExampleThread extends Thread {

    private final static long SLEEP_TIME = 2000l;

    private String name;

    private String code;

    public ExampleThread(String name, String code) {
        this.name = name;
        this.code = code;
    }

    @Override
    public void run() {
        // run 方法内处理业务逻辑
        try {
            log.debug(" 继承 Thread 类实现多线程,开始......");
            log.debug("{}:{}", name, code);
            Thread.currentThread().sleep(SLEEP_TIME);
            log.debug("执行业务逻辑啦......");
            log.debug("......*......");
            log.debug(".....***.....");
            log.debug("....*****....");
            log.debug("...*******...");
            log.debug("......*......");
            log.debug("{}:{}", name, code);
            log.debug(" 继承 Thread 类实现多线程,结束......");
        } catch (InterruptedException e) {
            log.error("线程内部错误", e);
        }
    }

    public static void main(String[] args) {
        List<String> list = new LinkedList<String>();
        ExampleThread exampleThreadOne = new ExampleThread("样例线程 1","THREAD---0001");
        exampleThreadOne.start();
        ExampleThread exampleThreadTwo = new ExampleThread("样例线程 2","THREAD---0002");
        exampleThreadTwo.start();
    }
}

 

2 实现 Runnable 接口

该方式与继承Thread类类似,无返回值,但是可以通过共现结果变量、标记的形式实现;

样例:

package com.study.thread;

import lombok.extern.slf4j.Slf4j;

/**
 * @auth zhangmj
 * @date 2019/2/11 14:51
 */
@Slf4j
public class ExampleRunnable implements Runnable {
    private final static long SLEEP_TIME = 2000l;

    private String name;

    private String code;

    public ExampleRunnable(String name, String code) {
        this.name = name;
        this.code = code;
    }

    @Override
    public void run() {
        // run 方法内处理业务逻辑
        try {
            log.debug(" 实现 Runnable 接口实现多线程,开始......");
            log.debug("{}:{}", name, code);
            Thread.currentThread().sleep(SLEEP_TIME);
            log.debug("执行业务逻辑啦......");
            log.debug(".......❤......");
            log.debug(".....❤❤❤.....");
            log.debug("....❤❤❤❤....");
            log.debug("...❤❤❤❤❤...");
            log.debug("..❤❤❤❤❤❤❤......");
            log.debug("{}:{}", name, code);
            log.debug(" 实现 Runnable 接口实现多线程,结束......");
        } catch (InterruptedException e) {
            log.error("线程内部错误", e);
        }
    }

    public static void main(String[] args) {
        ExampleRunnable exampleRunnableOne = new ExampleRunnable("Runnable 样例线程 1","Runnable---0001");
        Thread threadOne = new Thread(exampleRunnableOne);
        threadOne.start();
        ExampleRunnable exampleRunnableTwo = new ExampleRunnable("Runnable 样例线程 2","Runnable---0002");
        Thread threadTwo = new Thread(exampleRunnableTwo);
        threadTwo.start();
    }
}

3 实现 Callable接口

该方式有返回值,实现方式与前两种有所不同,需要 实现类FutureTask配合使用;

样例:

package com.study.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * @auth zhangmj
 * @date 2019/2/11 14:56
 */
@Slf4j
public class ExampleCallable implements Callable<String> {

    private final static long SLEEP_TIME = 2000l;

    private String name;

    private String code;

    public ExampleCallable(String name, String code) {
        this.name = name;
        this.code = code;
    }

    @Override
    public String call() throws Exception {
        // run 方法内处理业务逻辑
        try {
            log.debug(" 实现 Callable 接口实现多线程,开始......");
            log.debug("{}:{}", name, code);
            Thread.currentThread().sleep(SLEEP_TIME);
            log.debug("执行业务逻辑啦......");
            log.debug(".......卍......");
            log.debug(".....卍卍卍.....");
            log.debug("....卍卍卍卍....");
            log.debug("...卍卍卍卍卍...");
            log.debug("..卍卍卍卍卍卍卍......");
            log.debug("{}:{}", name, code);
            log.debug(" 实现 Callable 接口实现多线程,结束......");
            StringBuffer sb = new StringBuffer();
            sb.append("name:").append(name).append(" code:").append(code);
            return sb.toString();
        } catch (InterruptedException e) {
            log.error("线程内部错误", e);
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        List<FutureTask<String>> taskList = new LinkedList<FutureTask<String>>();
        ExampleCallable exampleCallableOne = new ExampleCallable("Callable 样例线程 1","Callable---0001");
        FutureTask<String> taskOne = new FutureTask<>(exampleCallableOne);
        taskList.add(taskOne);
        Thread threadOne = new Thread(taskOne);
        threadOne.start();

        ExampleCallable exampleCallableTwo = new ExampleCallable("Callable 样例线程 2","Callable---0002");
        FutureTask<String> taskTwo = new FutureTask<>(exampleCallableTwo);
        taskList.add(taskTwo);

        Thread threadTwo = new Thread(taskTwo);
        threadTwo.start();
        // 打印返回结果
        for (FutureTask<String> futureTask : taskList) {
            log.debug("返回结果:{}", futureTask.get());
        }
    }
}

 

三 总结

以上三种实现方式,都是采用直接 新建线程实例的方式实现的。

在正常的业务实现中,可以实现使用,但是会有一定效率降低,通常会使用线程池的方式。

 

 

转载于:https://my.oschina.net/zhangmingjie/blog/3008937

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值