关于java:Java多线程通俗易懂解读

01. 理解Java程序运行过程

  1. java程序,都是通过java命令来运行,实际上,java命令是启动一个jvm过程;jvm就是java虚拟机,jvm翻译java字节码,找到main入口,启动java线程,从main入口,执行java程序;通常执行main的java线程是main线程。
  2. mian线程执行java代码过程中,可能会遇到创立新的线程状况,新创建的线程启动后,和main线程并行执行。即便main线程退出后,其余创立的线程可能还在运行。

程序运行的实质

  • 不论是什么语言的程序,最终都是转换成为机器010101…码执行,于是所有程序都能够形象成执行者和工作清单,执行者最终体现在硬件上,最常见的是CPU,通用是处理器,在软件程序语言层面,执行者就是常说的过程/线程。另外一个是工作清单,执行者要工作,必须有一份工作清单,程序代码能够看作是工作清单,是人和机器交换的语言。人要驱动机器干活,必须说机器能听懂的语言,这就是程序语言。
  • 一份代码,为什么会呈现多线程问题。打个比方,一份代码好比一份菜单做菜过程,假如要做10盘同样的菜,为了快,要10集体同时炒菜;设想一下,10集体同时用一个锅,炒进去的菜能吃吗。这个菜单做菜步骤就是一份代码,10个厨师同时炒菜就是10个线程并发,按理说并发也没问题,然而,因为共享一个锅,问题就呈现了。这就是多线程问题。

多线程问题例子-计算固定字符串的md5值


public class Test {
    private static MessageDigest digest;
    public static void main(String[] args) throws Exception {
        try {
            digest = MessageDigest.getInstance("md5");
        } catch (Exception e) {
            e.printStackTrace();
        }
        calcMd5();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                calcMd5();
            }).start();
        }
    }
    private static void calcMd5() {
        String str = "test";
        byte[] res = digest.digest(str.getBytes(Charset.forName("utf-8")));
        StringBuilder sb = new StringBuilder();
        for (byte b : res) {
            sb.append(String.format("%02x", b));
        }
        System.out.println(Thread.currentThread().getName() + ":" + sb.toString());
    }
}

test的md5值是098f6bcd4621d373cade4e832627b4f6,

但上述代码,多线程执行,有的线程计算结果有问题,一次执行后果如下

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理