• 深入理解多线程(一)


    深入理解多线程(一)

    1.多线程的原理

    1.1 代码展示多线程

    为了演示多线程,我们用一个代码来展示多线程的效果:

    public class App {
        public static void main(String[] args) throws InterruptedException {
            //子线程
            new Thread(() -> {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+":小强");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            //主线程
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName()+":旺财");
                Thread.sleep(100);
            }
        }
    }
    

    流程图:

    程序启动运行main时候,java虚拟机启动一个进程,主线程main在main()调用时候被创建。随着调用Thread的对象的start方法,另外一个新的线程也启动了,这样,整个应用就在多线程下运行。 通过这张图我们可以很清晰的看到多线程的执行流程。

    1.2 图解多线程时内存状态图

    多线程执行时,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。进行方法的压栈和弹栈。

    jvm虚拟机中,堆中放的是对象和数据,栈中放的是方法,方法区中放的是class类文件

    2. 创建线程的两种方法

    2.1 继承Thread类

    public class MyThread extends Thread{
        public MyThread(String name){
            super(name);
        }
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("小强");
            }
        }
    }
    
    //调用
    new MyThread("myThread").start
    

    2.2 实现Runable接口

    public class MyThread implements Runnable{
        @Override
        public void run() {
            System.out.println("myThread");
        }
    }
    //调用
    Thread thread=new Thread(new MyThread());
    thread.start()
    

    我们更倾向于使用匿名内部类:

    new Thread(() -> {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+":小强");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    

    通过实现Runnable接口,使得该类有了多线程类的特征。run()方法是多线程程序的一个执行目标。所有的多线程

    代码都在run方法里面。Thread类实际上也是实现了Runnable接口的类

    在启动多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread 对象的start()方法来运行多线程代码。

    实际上所有的多线程代码都是通过运行Thread的start()方法来运行的。因此,不管是继承Thread类还是实现

    Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的

    2.3 两者的优劣

    如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

    总结:

    实现Runnable接口继承Thread类所具有的优势:

    1. 适合多个相同的程序代码的线程去共享同一个资源。
    2. 可以避免java中的单继承的局限性。
    3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
    4. 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。

    扩充:在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用

    java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进

    程。

  • 相关阅读:
    postgres 类型转换 cast 转
    postgresql Delete+ join
    输出特定格式的查询内容到文本(不是导出查询结果)
    八步搞定亚马逊中国区HTTPS负载均衡器设置
    这辈子只能碰到一次! 记一次SSL无故被撤消!
    亚马逊S3数据迁移到中国区
    python2 微信三方登录 中文乱码
    GitLab Wiki 内容恢复版本管理
    Django rest_framework 实用技巧
    Django rest_framework 加入时间间隔
  • 原文地址:https://www.cnblogs.com/jimlau/p/12463476.html
Copyright © 2020-2023  润新知