【Java EE】多线程(一)

简介: 【Java EE】多线程(一)


1. 进程和多线程的概念

1.1 进程

提到多线程就不得不提及“进程”这个概念。

进程:进程是操作系统结构的基础;是一次程序的执行;是一个程序及其数据在处理机上顺序执行时发生的活动;在程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。

举例:


我们可以将一个正在操作系统中运行的.exe程序理解成进程,进程是受操作系统管理的基本运行单元.

1.2 线程

线程:线程就可以理解成是在进程中独立的子任务。

多线程:多线程指的就是一个 .exe 程序同时执行多个子任务


举例:

运行QQ.exe时就有很多子任务在同时运行。比如:好友视频线程、下载文件线程、传输数据线程、发送表情线程等等,这些不同任务或者功能都可以同时运行,其中每一项任务完全可以理解成理“线程”在工作,传文件,发送图片表情等能有对应的线程在后台默默运行。


多线程的优点:使用多任务操作系统 Windows 后,可以最大限度地利用 CPU 的空闲时间处理其他的任务,比如一边让操作系统处理正在由打印机打印的数据,一般使用 Word 编辑文档。而 CPU 在这些任务之间不停地切换,由于切换的速度非常快,给使用者的感受就是这些任务似乎在同时运行。所以使用多线程技术后,可以在同一时间运行更多不同种类的任务。


小结:


有了多线程,我们就可以让程序同时做多件事情

多线程的作用:提高效率

多线程的应用场景:只要你想让多个事情同时运行就需要多线程,比如:软件中的消耗操作、所有的聊天软件、所有的服务器。

2. 并发和并行

2.1 并发

并发:在同一个时刻,有多个指令在单个 CPU 上交替执行


举例:我在打游戏的时候。又想喝可乐,于是我的右手一会拿鼠标,一会拿可乐,那么此时由于我的手速非常的快,在鼠标和可乐之间来回交替执行,此时我们就可以看作是并发,这里右手就是当做 CPU,鼠标和可乐就当做线程1和线程2,CPU 就是在这两条线程之间进行交替执行

红色的线比做 CPU ,蓝色的线比做 线程。

2.2 并行

并行:在同时一个时刻,有多个指令在多个 CPU 上同时执行



红色的线比做 CPU ,蓝色的线比做 线程。

有人会疑问了我们的电脑上不是只有一个 CPU?为啥上图有两个 CPU 呢?


但是我们的电脑的 CPU 可以分为:2核4线程、4核8线程、8核16线程、16核32线程、32核64线程等等。这里线程的数量就是电脑能同时运行的线程。


这里我们用2核心4线程举例:

它可以同时运行4条线程,所以如果你的电脑当中只有4条线程,那么它就可以不用切换的,但是如果线程越来越多,那么这4条红线就会在多个线程之间随机的进行切换,所以在计算机中并发和并行有可能同时都在发生的

3. 多线程的实现方式

3.1继承 Thread 类

步骤:

  1. 定义类继承 Thread
  2. 重写 run方法
  3. 创建实例
  4. 启动线程


代码:

// 1.继承 Thread类
class MyThread extends Thread{
    // 2. 重写 run方法
    @Override
    public void run() {
        // 线程代码
        while (true) {
            System.out.println("hello thread");
            // sleep方法:休眠
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

public class Test {
    public static void main(String[] args) {
        // 3. 创建实例
        MyThread t = new MyThread();
        // 4.启动线程 
        t.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

运行结果:

【注意】:多线程是异步的,所以千万把 idea 里代码的顺序当成线程执行的顺序,线程被调用的时机是随机的。


3.2 实现 Runnale 接口

步骤:

  1. 实现 Runnale 接口
  2. 重写 run 方法
  3. 创建实例,调用 Thread 的构造方法时将 Runnable 对象作为 target 参数
  4. 启动线程


代码:

// 1. 实现Runnable 接口
class MyRunnable implements Runnable {
    // 重写 run 方法
    @Override
    public void run() {
        while (true) {
            System.out.println("hello Thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

public class Test3 {
    public static void main(String[] args) {
        // 3. 创建实例,调用 Thread 的构造方法时将 Runnable 对象作为 target 参数
        Thread t = new Thread(new MyRunnable());
        // 4. 启动线程
        t.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}


运行结果

3.3 其他形式

  • 匿名内部类创建 Thread 子类对象

代码:

public class Test4 {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                while (true) {
                    System.out.println("hello Thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}


运行结果:

  • 匿名内部类创建 Runable 子类对象

代码:

public class Test5 {
    public static void main(String[] args) {
        new Thread(new MyRunnable()) {
            @Override
            public void run() {
                while (true) {
                    System.out.println("hello Thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

运行结果:

  • lambda 表达式创建 Runnable 子类对象

代码:

public class Test6 {
    public static void main(String[] args) {
        Thread t =  new Thread(() -> {
            while (true) {
                System.out.println("hello Thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();

        while (true) {
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

运行结果:

相关文章
|
3天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)
|
14天前
|
监控 Java 调度
【Java学习】多线程&JUC万字超详解
本文详细介绍了多线程的概念和三种实现方式,还有一些常见的成员方法,CPU的调动方式,多线程的生命周期,还有线程安全问题,锁和死锁的概念,以及等待唤醒机制,阻塞队列,多线程的六种状态,线程池等
75 6
【Java学习】多线程&JUC万字超详解
|
7天前
|
Java 调度 开发者
Java并发编程:深入理解线程池
在Java的世界中,线程池是提升应用性能、实现高效并发处理的关键工具。本文将深入浅出地介绍线程池的核心概念、工作原理以及如何在实际应用中有效利用线程池来优化资源管理和任务调度。通过本文的学习,读者能够掌握线程池的基本使用技巧,并理解其背后的设计哲学。
|
7天前
|
缓存 监控 Java
Java中的并发编程:理解并应用线程池
在Java的并发编程中,线程池是提高应用程序性能的关键工具。本文将深入探讨如何有效利用线程池来管理资源、提升效率和简化代码结构。我们将从基础概念出发,逐步介绍线程池的配置、使用场景以及最佳实践,帮助开发者更好地掌握并发编程的核心技巧。
|
4天前
|
Java 调度 开发者
Java中的多线程基础及其应用
【9月更文挑战第13天】本文将深入探讨Java中的多线程概念,从基本理论到实际应用,带你一步步了解如何有效使用多线程来提升程序的性能。我们将通过实际代码示例,展示如何在Java中创建和管理线程,以及如何利用线程池优化资源管理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧,帮助你更好地理解和应用多线程编程。
|
9天前
|
缓存 监控 Java
java中线程池的使用
java中线程池的使用
|
8天前
|
算法 Java 数据处理
Java并发编程:解锁多线程的力量
在Java的世界里,掌握并发编程是提升应用性能和响应能力的关键。本文将深入浅出地探讨如何利用Java的多线程特性来优化程序执行效率,从基础的线程创建到高级的并发工具类使用,带领读者一步步解锁Java并发编程的奥秘。你将学习到如何避免常见的并发陷阱,并实际应用这些知识来解决现实世界的问题。让我们一起开启高效编码的旅程吧!
|
13天前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
|
10天前
|
Java 开发者
Java中的多线程编程基础与实战
【9月更文挑战第6天】本文将通过深入浅出的方式,带领读者了解并掌握Java中的多线程编程。我们将从基础概念出发,逐步深入到代码实践,最后探讨多线程在实际应用中的优势和注意事项。无论你是初学者还是有一定经验的开发者,这篇文章都能让你对Java多线程有更全面的认识。
15 1
|
17天前
|
Java 调度
Java中的多线程基础与实践
【8月更文挑战第31天】本文将深入浅出地讲解Java中多线程的基础知识,并通过实例展示如何在Java程序中实现多线程。我们将从多线程的基本概念出发,逐步深入到线程的创建、控制以及同步机制,最后通过一个简易版的生产者消费者模型来实践这些知识点。文章旨在帮助初学者快速掌握多线程编程的关键技能,并理解其背后的原理。