多线程的使用

本文详细介绍了Java中的多线程概念,包括进程与线程的区别、并发与并行,以及线程的优缺点。讲解了创建线程的两种方式:继承Thread类和实现Runnable接口,并探讨了线程的常用方法如sleep。此外,文章还讨论了线程同步的同步代码块和同步方法,以及如何处理死锁问题。最后,提到了守护线程的概念及其在实际开发中的应用。
摘要由CSDN通过智能技术生成


前言

本文主要浅Java基础中的多线程


提示:以下是本篇文章正文内容,下面案例可供参考

一、概念

1.1什么是进程?

> 独立运行的应用程序叫进程

​ 什么是应用程序,就是咱们打开各个软件,比如 谷歌浏览器,360,qq音乐等这些软件,他们都是独立的一个运行起来的软件,叫应用应用程序,

​ 代码里面写过Demo1 Demo2这些类,也可以叫一个应用程序,也可以叫进程

​ 进程需要通过系统的分配,获取系统中的cpu,内存,显卡,网络等。

​ 独立性 :qq和谷歌浏览器没有关系的,他们之间是独立的

​ 互斥性:咱们软件的运行都是在抢占cpu,谁抢过谁先执行。

​ 直到为什么有的时候一个软件会卡,让你等待。是因为这个软件在抢占cpu

​ 的时候,没有抢占过别的软件。所以要么关闭软件,等待响应。

1.2什么是线程?

进程是有多个线程组成的,而且一个进程至少得有一个线程
线程是进程的灵魂所在,看不见摸不着。进程可以看到,就是正在运行的应用程序,但是内存是怎么运行的呢,其实是线程在运行的
线程是组成进程的最小单位。
如果把一个人比作一个进程,那么细胞就是一个线程
线程具有什么特性:
1.抢占式运行: CPU执行应用程序的时候是按照时间片执行的,而且单位时间内时间片被线程相互抢占式的运行
例子:卫生间就三个位置,一个班级有100个人,抢占这个位置,谁抢到谁就先用。等你释放以后,其他人再抢,线程很忙,不断的抢占CPU的执行权,不断的释放。
2.资源共享性:
一个线程可以共享当前资源,cpu、内存
QQ这个进程,假如占用的运行内存为3MB,QQ内的多个线程可以共同去抢占这3MB的运行内存。
进程之间能资源共享吗?线程之间能资源共享吗?
进程之间不能资源共享 IDEA和QQ这是两个进程,不可以共享资源
线程之间可以共享资源,在一个应用程序中,抢占同一个资源
一个JAVA应用程序至少有几个线程?
2个线程:一个为main主函数线程,另外一个为JVM垃圾回收线程。

1.3进程和线程的区别?

进程是一个完整的应用程序,而且一个线程至少有一个线程,可以把进程看做一个生产车间。线程是进程的一个执行的功能,可以看做一个生产车间内的一条生产线。
一个生产车间是有多条生产线组成的,一个应用程序是有多个线程组成的。
进程申请的是Windows系统的资源
线程申请的是进程内的资源。
多个线程在执行的时候,cpu会根据每个线程分配时间片来随机轮流执行。
每个线程最多占用的时间片大概是20ms,过了这个时间片就切换到另外一个线程了。
将卫生间比作一个应用程序,一个进程
在这个进程中,有100个(学生)线程,去申请这个卫生间的资源,这个卫生间的资源有3MB(三个坑位)。每个学生去抢占这个坑位,只给你留的时间片大概为20ms。保证这个进程一直在执行,没有挂掉,视觉感觉不到线程在在抢占资源,感觉到的是应用程序一直在执行。

1.4并发和并行

并发:同时发生,轮流交替执行
并行:真正意义的同时执行
举个例子:

​ 比如你点了两盘菜,最终你都要将这两盘菜吃完,。

​ 从老板的角度有来看。属于同时吃完的。但是严格意义上来讲,轮流交替吃的。属于并发。

​ 并行:比如你和你同桌两个人,一人点了一个菜,你吃你的我吃我的,并行

1.5线程的优缺点

优点:
1.提高资源的利用率,cpu不至于空闲
2.电脑可以执行多个功能
3.提升用户的体验
缺点:
1.加重了cpu 的负担
2.降低cpu执行其它线程的概率,可能会导致线程的卡顿
3.共享资源的问题
4.会产生死锁

二、创建线程的两种方式

2.1方式一:继承Thread类

方式一:
①自定义线程类去继承Thread类,重写run方法
②在main主函数中创建自定义线程类的实例,然后调用start()方法启动线程。

代码示例如下:

//1.自定义线程类去继承Thread类
class MyThread2 extends Thread{
   

    //2.重写run()方法
    @Override
    public void run() {
   
        for (int i = 0; i < 100; i++) {
   
            System.out.println("我是MyThread2里面的线程");
        }
    }
}
public class Demo4 {
   
    public static void main(String[] args) {
   
        //3.创建自定义的线程类的对象
        MyThread2 myThread2 = new MyThread2();

        //4.通过自定义的线程类的对象调用start()方法
        myThread2.start();
        //start()方法的作用:①启动当前线程②调用当前线程的run()方法。

        for (int i = 0; i < 100; i++) {
   
            System.out.println("我是main主线程");
        }
    }
}

2.2方式二、实现Runnable接口

方式二:
① 自定义线程类,去实现Runnable接口,重写run()方法
②在main主函数中 实例化自定义的线程类,将实例化的对象作为参数传递给Thread的带参构造方法,创建Thread类的对象
③通过Thread类的对象调用start()方法,启动线程。

代码示例如下:

//1.自定义线程类去实现Runnable接口
class MyThread3 implements Runnable{
   

    //2.重写run()方法
    //将该线程要执行的功能写在run()方法内
    @Override
    public void run() {
   
        for (int i = 0; i < 100; i++) {
   
            System.out.println("我是MyThread3的线程");
        }
    }
}
public class Demo5 {
   
    public static void main(String[] args) {
   
        //3.实例化自定义线程类的对象
        MyThread3 myThread3 = new MyThread3();

        //4.将自定义线程类的对象作为参数传递给Thread类的带参构造方法
        //创建Thread类的对象
        Thread thread = new Thread(myThread3);

        //5.通过Thread类的对象调用start()
        thread.start();
        //start():①启动当前线程②调用当前线程的run()

        for (int i = 0; i < 100; i++) {
   
            System.out.println("我是main主线程");
        }

    }
}

三、线程类常用的方法

构造方法:

Thread();//创建了一个线程对象
Thread(Runnable target);//创建线程对象,传入的是Runnable接口的实现类
Thread(Runnable target,String name);//创建线程对象,传入的是Runnable接口的实现类,和当前线程的名字

成员方法:

static Thread currentThread();//获取当前线程的对象
void setName(String name);//设置当前线程的名字
String getName();//获取当前线程的名字
void setPriority(int newPriority);//设置当前线程的优先级
优先级只能增加线程的执行概率,不一定优先,线程的默认优先级为5,取值范围为1-10,优先级最高的为10
int getPriority();//获取当前线程的优先级
static void sleep(long millis);//让当前线成进行休眠,传入的是一个long类型的数据(毫秒数)

代码示例如下:

class MyThread5 implements Runnable{
   

    @Override
    public void run() {
   
        //获取当前线程对象
        Thread thread = Thread.currentThread();
        //获取当前线程的优先级
        System.out.println(thread.getPriority());//5
        System.out.println(thread.getName());//通过当前的线程对象获取线程的名字

        for (int i = 0; i < 100; i++) {
   
            System.out.println(thread.getName() + " :"+i);
        }
    }
}
class MyThread6 implements Runnable{
   

    @Override
    public void run() {
   
        Thread thread = Thread.currentThrea
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小yu别错过

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

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

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

打赏作者

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

抵扣说明:

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

余额充值