并发与并行,线程的创建

本文详细介绍了Java中的并发与并行概念,包括微观上的并行执行和并发执行。同时,讲解了四种创建线程的方法,如继承Thread类和实现Runnable接口。还讨论了线程的抢占式执行原理,并通过示例展示了线程交替执行的情况。最后,阐述了使用多线程提高程序效率的优势以及合理使用线程的重要性。
摘要由CSDN通过智能技术生成

目录

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方法开始执行该线程。

class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("run1");
    }
}
public class Demo1 {
    public static void main(String[] args) {
        MyThread thread=new MyThread();
        thread.start();
    }
}

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

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

lass MyRunnable implements Runnable{

    @Override
    public void run() {
        System.out.println("run1");
    }
}
public class Demo2 {

    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread=new Thread(myRunnable,"我的线程");
        thread.start();

        System.out.println("run2");
        
    }
}

2.3、匿名内部类创建Thread类

public class Demo3 {
    public static void main(String[] args) {
        Thread thread=new Thread (){
            @Override
            public void run() {
                System.out.println("run1");
            }
        };
        thread.start();
        System.out.println("run2");
    }
}

 2.4、匿名内部类实现Runnable

public class Demo4 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("run1");     
            }
        });
        t.start();
        System.out.println("run2");
    }
}

3、线程的抢占式执行

 具体线程创建如下

class MyThread extends Thread{
    @Override
    public void run() {
        while (true){
            System.out.println("run1");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Demo1 {
    public static void main(String[] args) {
        MyThread t=new MyThread();
        t.start();

        while(true){
            System.out.println("run2");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

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

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

4、使用多线程的优势

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东莞呵呵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值