java 多线程入门

java 多线程入门

1.多线程是什么?

按本人的理解,多线程就是让你的代码同时(并行)执行,缩短代码的运行时间。

2.举个例子

有个业务需求,需要发送邮件和发送短信。发送邮件和发送短信的方法模拟如下:

import java.util.Random;

/**
 * 发邮件类
 */
public class EmailUtil {
    /**
     * 发邮件
     * @param message  消息
     * @return 如果成功返回true,失败返回false
     */
      public static boolean sendEmail(String message){
          try {
              Thread.sleep(4000); //模拟发邮件需要3秒
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          System.out.println("正在发送邮件,内容为:"+message);
          int res = new Random().nextInt(2); //随机产生0(成功)和1(失败)
          if(res==0){
              System.out.println("发送邮件成功");
              return true;
          }else{
              System.out.println("发送邮件失败");
              return false;
          }
      }
}
import java.util.Random;

/**
 * 发短信类
 */
public class PhoneUtil {
    /**
     * 发短信
     * @param message  消息
     * @return 如果成功返回true,失败返回false
     */
    public static boolean sendPhoneMessage(String message){
        try {
            Thread.sleep(4000); //模拟发邮件需要3秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("正在发送短信,内容为:"+message);
        int res = new Random().nextInt(2); //随机产生0(成功)和1(失败)
        if(res==0){
            System.out.println("发送短信成功");
            return true;
        }else{
            System.out.println("发送短信失败");
            return false;
        }
    }
}

2.1 串行发送邮件,发送短信

程序的模拟业务如下:

public class Main {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        String message = "boss,I want more money!!!";
        sendMessage(message);
        long endTime = System.currentTimeMillis();
        System.out.println("发送消息结束!!!耗时:"+(endTime-startTime)+"毫秒");
    }

    /**
     * 串行调用发邮件,发短信
     * @param message 消息
     */
    public static void sendMessage(String message){
        EmailUtil.sendEmail(message);
        PhoneUtil.sendPhoneMessage(message);
    }
}

串行调用先发邮件后发短信 。由于发短信和发邮件代码模拟都是耗时4000毫秒。因此,程序的总耗时应该是8000毫秒以上,我们来看下运行结果:

正在发送邮件,内容为:boss,I want more money!!!
发送邮件失败
正在发送短信,内容为:boss,I want more money!!!
发送短信成功
发送消息结束!!!耗时:8016毫秒

2.2 并行发送邮件,发送短信

如果我们利用多线程,发邮件和发短信同时进行,代码应该怎么写呢?(道友们可以百度下java线程应该怎么写,下面我直接贴出代码)

public class Main {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        String message = "boss,I want more money!!!";
//        sendMessage(message);
        sendMessageWithThread(message);
        long endTime = System.currentTimeMillis();
        System.out.println("发送消息结束!!!耗时:"+(endTime-startTime)+"毫秒");
    }

    /**
     * 串行调用发邮件,发短信
     * @param message 消息
     */
    public static void sendMessage(String message){
        EmailUtil.sendEmail(message);
        PhoneUtil.sendPhoneMessage(message);
    }

    /**
     * 多线程并行调用发邮件,发短信
     * @param message
     */
    public static void sendMessageWithThread(String message){
        Thread t1 = new Thread(()->EmailUtil.sendEmail(message));
        Thread t2 = new Thread(()->PhoneUtil.sendPhoneMessage(message));
        t1.start();
        t2.start();
        try {
            t1.join(); //让t1线程执行完,再往下执行main方法
            t2.join(); //让t2线程执行完,再往下执行main方法
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

下面我们再来看多线程并行的运行结果

正在发送邮件,内容为:boss,I want more money!!!
正在发送短信,内容为:boss,I want more money!!!
发送邮件失败
发送短信成功
发送消息结束!!!耗时:4041毫秒

2.3 并行发送邮件,发送短信,并返回结果

​ 细心的道友们发现,发送邮件和发送短信的调用是有可能失败的。但是上面的多线程没有返回结果。如果我们需要返回结果,程序该怎么写呢?(先思考一下,代码如下)

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        String message = "boss,I want more money!!!";
//        sendMessage(message);
//        sendMessageWithThread(message);
        sendMessageWithCallBack(message);
        long endTime = System.currentTimeMillis();
        System.out.println("发送消息结束!!!耗时:"+(endTime-startTime)+"毫秒");
    }

    /**
     * 串行调用发邮件,发短信
     * @param message 消息
     */
    public static void sendMessage(String message){
        EmailUtil.sendEmail(message);
        PhoneUtil.sendPhoneMessage(message);
    }

    /**
     * 多线程并行调用发邮件,发短信
     * @param message 消息
     */
    public static void sendMessageWithThread(String message){
        Thread t1 = new Thread(()->EmailUtil.sendEmail(message));
        Thread t2 = new Thread(()->PhoneUtil.sendPhoneMessage(message));
        t1.start();
        t2.start();
        try {
            t1.join(); //让t1线程执行完,再往下执行main方法
            t2.join(); //让t2线程执行完,再往下执行main方法
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 多线程并行调用发邮件,发短信
     * @param message 消息
     * @return 返回发送邮件和发送短信的结果
     */
    public static List<Boolean> sendMessageWithCallBack(String message){
        ExecutorService executorService = Executors.newCachedThreadPool();
        Callable<Boolean> callable1 = ()->EmailUtil.sendEmail(message);
        Callable<Boolean> callable2 = ()->PhoneUtil.sendPhoneMessage(message);
        Future<Boolean> future1 = executorService.submit(callable1);
        Future<Boolean> future2 = executorService.submit(callable2);
        List<Boolean> res = new ArrayList<>();
        try {
            res.add(future1.get());
            res.add(future2.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        executorService.shutdown();
        System.out.println("发送邮件,是否成功:"+res.get(0));
        System.out.println("发送短信,是否成功:"+res.get(1));
        return res;
    }
}

打印结果如下:

正在发送短信,内容为:boss,I want more money!!!
正在发送邮件,内容为:boss,I want more money!!!
发送短信失败
发送邮件成功
发送邮件,是否成功:true
发送短信,是否成功:false
发送消息结束!!!耗时:4052毫秒

3.总结

以上的例子,是本人对多线程入门的简单思考。当然,多线程远不止如此。还有锁,线程通信等等一系列问题。本篇文章只起一个入门的效果。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值