关于多线程编程的一些基础用法~

前提:关于为啥要有进程?

因为系统支持多任务,需要并发编程,通过多进程就可以实现并发编程,但是又问题~

创建进程需要分配资源(内存资源、文件资源),销毁进程还需要释放资源,对于资源的申请和释放又是一个非常低效的操作,如果频繁的调度进程,成本是比较高的~


如何解决低效这个问题呢?

方法一:进程池:(数据库连接池、字符串常量池)

             申请完之后并不进行真正的释放,只是把它归还到池里,下次再使用进程时直接去池

             里拿,跳过申请释放的过程 ,这时整体的开销就大大降低了

虽然进程池能解决上述问题,提高效率,但是使用进程池也存在着一定的问题,就是消耗的系统资源太多了,因为进程池里的闲置进程,不使用时也在消耗着系统资源(不适用于资源紧张的情况)

方法二:使用线程来实现并发编程:

原因:线程比进程更轻量,每个进程可以执行一个任务,每个进程也能执行一个任务,也能够并发编程

创建线程的成本比创建进程要低很多,销毁线程的成本也比销毁进程低很多,调度线程的成本也比调度进程低很多


为什么线程比进程更轻量?

进程重量是重在资源的申请和释放,而线程是包含在进程中的,一个进程中的多个线程,公用同一份资源(内存+文件),只是在创建进程的第一个线程的时候(由于要分配资源),成本是相对高的,后续这个进程中再创建其他线程,这个时候成本会更低些(因为不必再分配资源了


可以把进程比作一个工厂,假设这个工厂要生产1W部手机

要想提高生产效率:

1、搞两个工厂,一个工厂生产5K部手机(相当于多创建了一个进程)

2、还是一个工厂,在一个工厂里多加一个生产线,两个生产线并行生产,一个生产线生产5K部手机(相当于多创建了一个线程)

最终生产1W部手机,用这两个办法花 的时间都差不多,但是成本上就有差异了

用第一种方法建公厂的话,需要新搞场地、新盖厂房……准备各种各样的东西,全都准备好了才能投入生产,但是用第二种方法,新加一个生产线,此时就不用再准备厂房啥的了,直接都是现成的,场地也是现成的……啥都不用准备,只需要一个新的生产线就可以了

此时可以发现搞线程比搞进程更高效~

但是不是加线程加的越多,效率就越快的,因为整体的硬件资源是有限的,如果线程很多,这些线程可能要竞争同一个资源,这时候整体的速度就受到了限制


 进程和线程的区别和联系:(重点)

1、进程包含线程,一个进程里可以有一个线程,也可以有多个线程

2、进程和线程都是为了处理并发编程这样的场景。但进程有问题,就是在频繁的创建和释放的时候效率低,相比之下,线程更轻量,创建和释放效率更高(轻量的原因:少了申请释放资源的过程)

3、操作系统创建进程,要给进程分配资源,进程是操作系统分配资源的基本单位

操作系统创建线程,是要在CPU上调度执行,线程是操作系统调度执行的基本单位

4、进程具有独立性,每个进程有各自的虚拟地址空间,一旦进程挂了,不会影响到其他进程

同一个进程中的多个线程,共用同一个内存空间,一个线程挂了,可能影响到其他线程,甚至导致整个进程崩溃


 在Java标准库中,提供的Thread来表示/操作线程

Thread类可视为是Java标准库提供的API

创建好的Thread实例,和操作系统中的线程是一一对应的关系

(因为操作系统提供了一组C语言风格的关于线程的API,Java对于这组API进一步封装成Thread类)


关于Thread类创建线程的具体方法:

方法一:创建一个继承Thread的子类,并重写run方法

class MyThread extends Thread{//创建Thread子类,相当于自己写的MyThread类针对标准库中的Thread类进行进一步的扩展
    @Override
    public void run() {//在这个方法里写这个线程里具体执行的代码
        System.out.println("hello thread");
    }
}
//最基本的创建线程的方法
public class Demo1 {
    public static void main(String[] args) {
    Thread t=new MyThread(); //new一个Thread的子类,换句话说在创建线程时,需要线创建一个子类继承自Thread,然后才能进行使用
    t.start();//此时系统才创建了线程,调用start之前系统中是没有创建线程的
    }
}

注意:

1.run方法中写的是在新创建的线程中要被执行的代码,并不是代表写完这个run方法,线程就创建好了(相当于把活安排好了,但是还没开始干)

2.需要调用start方法,此时才真正的在系统中创建了线程,才真正开始执行run操作,在调用start之前,系统中是没有创建出线程的

并发执行线程:

自己创建的 t 线程和自动创建的 main 线程(在java进程中,至少会有一个调用main方法的线程),就是并发执行的关系(宏观上看起来是同时执行)

class MyThread2 extends Thread{
    @Override
    public void run() {
        while(true){//无限循环
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);//1s中打印一下
            } catch (InterruptedException e) {//多线程中常见异常-》线程被提前中断了,这里是执行sleep操作抛出的异常

            }
        }
    }
}
public class Demo2 {
    public static void main(String[] args) {
        Thread t=new MyThread2();//自己创建的t线程
        t.start();//此时创建好t线程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值