• 并发与并行,线程的创建


    目录

    1、并发和并行

    并发(Concurrency)

    并行 (Parallelism)

    2、线程的创建

    2.1、继承Thread类,重写run方法

    2.2、实现Runnable接口,重写run方法  

    2.3、匿名内部类创建Thread类

     2.4、匿名内部类实现Runnable

    3、线程的抢占式执行

    4、使用多线程的优势


    1、并发和并行

    微观上的并行就是多个线程在多核CPU上面同时执行,这样提高了程序的执行效率,

    微观上的并发是把多个任务拆开然后执行一部分再迅速切换到另外一个任务

    并发(Concurrency)

    并行 (Parallelism)

    一般我们的程序就是在宏观上面并发执行,但是在微观上面是并发+并行执行。但是由于并发时程序切换的速度非常快,所以我们在感官上面感觉不出差别,所以在宏观上我们把这种执行方式称谓并发执行。

    2、线程的创建

    2.1、继承Thread类,重写run方法

     我们可以通过写一个继承了Thread的类,来创建一个线程,因为Thread类实现了Runnable接口,所以,我们自己写的线程类就要重写run方法。、

    创造一个线程类继承Thread方法 ,在main函数里面实例化该类,再调用start方法开始执行该线程。

    1. class MyThread extends Thread{
    2. @Override
    3. public void run() {
    4. System.out.println("run1");
    5. }
    6. }
    7. public class Demo1 {
    8. public static void main(String[] args) {
    9. MyThread thread=new MyThread();
    10. thread.start();
    11. }
    12. }

    2.2、实现Runnable接口,重写run方法  

    创建一个线程类,实现Runnable接口,再在main线程中先实例化一个自己写的线程类,再把该对象当作参数去实例化一个Thread类。

    1. lass MyRunnable implements Runnable{
    2. @Override
    3. public void run() {
    4. System.out.println("run1");
    5. }
    6. }
    7. public class Demo2 {
    8. public static void main(String[] args) {
    9. MyRunnable myRunnable = new MyRunnable();
    10. Thread thread=new Thread(myRunnable,"我的线程");
    11. thread.start();
    12. System.out.println("run2");
    13. }
    14. }

    2.3、匿名内部类创建Thread类

    1. public class Demo3 {
    2. public static void main(String[] args) {
    3. Thread thread=new Thread (){
    4. @Override
    5. public void run() {
    6. System.out.println("run1");
    7. }
    8. };
    9. thread.start();
    10. System.out.println("run2");
    11. }
    12. }

     2.4、匿名内部类实现Runnable

    1. public class Demo4 {
    2. public static void main(String[] args) throws InterruptedException {
    3. Thread t=new Thread(new Runnable() {
    4. @Override
    5. public void run() {
    6. System.out.println("run1");
    7. }
    8. });
    9. t.start();
    10. System.out.println("run2");
    11. }
    12. }

    3、线程的抢占式执行

     具体线程创建如下

    1. class MyThread extends Thread{
    2. @Override
    3. public void run() {
    4. while (true){
    5. System.out.println("run1");
    6. try {
    7. Thread.sleep(1000);
    8. } catch (InterruptedException e) {
    9. e.printStackTrace();
    10. }
    11. }
    12. }
    13. }
    14. public class Demo1 {
    15. public static void main(String[] args) {
    16. MyThread t=new MyThread();
    17. t.start();
    18. while(true){
    19. System.out.println("run2");
    20. try {
    21. Thread.sleep(1000);
    22. } catch (InterruptedException e) {
    23. e.printStackTrace();
    24. }
    25. }
    26. }
    27. }

     用我们写出的MyThread类实例化出的t对象,再使用t对象调用start方法开始运行该线程。t线程循环执行输出“run1”再加上我们在main线程中执行输出“run2”,连各个线程并发执行的结果就是你这样。

     这是因为两个线程在执行的时候谁先执行是不确定的,我们在两个线程中都调用了sleep(1000)方法,也就是使该线程休眠1s,两个线程同时休眠一秒后同时进入到就绪状态,但是执行哪一个线程就是一个不确定的事件,这也就是线程的抢占式执行,编写多线程代码时要保证,所有可能的调度结果,保证每种情况下都不出bug,这就是多线程程序往往bug最难修改,因为只有在特定情况下才会出现的bug,我们很难再修改的时候使该bug复现。

    4、使用多线程的优势

    CPU在发展中,为了满足算力的需求由单核心逐渐变成了现在的多核心,例如下:

    而充分利用多核心的CPU就是我们多线程的任务,也就是说多线程的优势就在于充分利用CPU资源,提高了程序的效率,但是线程也不是越多越好,过多的线程反而会影响到CPU的调度,降低运行效率,而且多线程由于线程安全问题,以及抢占式执行等一系列问题,使得代码容易出现bug,维护成本也更高,所以说我们要合理的利用多线程,来提高程序的效率,而不能一味的追求代码实现的复杂性,使用大量的线程。 

  • 相关阅读:
    视频教程 | Demo演示视频上线,几分钟了解一个长安链使用技巧
    [极客大挑战 2019]Knife 1(两种解法)
    解决“org.apache.catalina.startup.Catalina.stopServer 未配置关闭端口。通过OS信号关闭服务器。服务器未关闭“
    [Linux]基础IO上(C文件操作 | 系统文件IO | 文件描述符fd | 缓冲区概念)
    微信小程序的民宿客房预订uniapp小程序
    [2022强网杯] polydiv和gamemaster
    RocketMQ高性能核心原理与源码架构剖析
    如何有序协同和管理多个研发项目?
    记录一次Maven依赖传递,模块之间依赖版本不一致问题
    Python之猜数字游戏
  • 原文地址:https://blog.csdn.net/dghehe/article/details/126779839