• 线程基础(一)


    活动地址:CSDN21天学习挑战赛

    一.并发与并行的概念

    1.程序:一个固定逻辑与数据的集合就是程序 例如 俄罗斯方块 贪吃蛇
    2.cpu:中央处理器 主要用于协调程序与硬件的工作
    
    • 1
    • 2

    那什么是并发与并行?
    先来一张图浅显了解一下并发和并行的区别吧。
    在这里插入图片描述

    大体上的解释是:
    并发(又称高并发):是同一个时间段执行两个,或者两个以上程序的,单核cpu交互(上面所说的时间片轮转是一种)的执行,由于cpu切换的速度很快,逻辑上我们任务并发是同时执行多个任务,实际上是交替执行

    例子:两个队伍的人在一个窗口打菜。

    并行:在同一时刻,执行两个或者是多个程序的时候,多核cpu同时执行(现象的电脑都是多核cpu)

    例子:多个人在多个咖啡机前排队。

    在这里插入图片描述

    二.线程与进程

    概念:
    进程运行在内存中的程序就是进程.

    每个进程都有⼀个独⽴的内存空间,⼀个应⽤程序可以同时运⾏多个进程;进程也是程序的⼀次执⾏过程,是系统运⾏程序的基本单位;系统运⾏⼀个程序即是 ⼀个进程从创建、运⾏到消亡的过程

    线程: 通向cpu的执行的路径就是线程。

    线程又分为单线程和多线程
    单线程:只有一条通向cpu的执行的路径
    多线程:多条通向cup的执行的路径
    注意:
    1.一个进程中能包含多个线程
    2.一个线程只能存在一个进程中。
    3.任务管理器里关闭的那个玩意就叫做进程

    在这里插入图片描述

    多线程的进程运行的流程图
    在这里插入图片描述

    三. 主线程与子线程

    在这里插入图片描述

    3.1主线程:

    主方法中,例如运行main方法函数的线程

    负责管理子线程,即子线程的启动、挂起、停止等等操作

    public class HelloWorld {
        public static void main(String[] args) {
    
            Thread mainThread = Thread.currentThread();
            System.out.println("我是主线程");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.2子线程:

    只能是理解为由主线程负责管理,即主线程负责启动,挂起,停止的线程为子线程

    3.3进程,主线程,子线程的关系图

    在这里插入图片描述

    四.线程的三种创建方法

    4.1 第一种 继承Thread重写run方法

    步骤:

    1.定义一个类去继承Thread
    2.重写run()方法,执行线程的操作
    3.实例化这个线程类的独享
    4.调用start()方法,开启线程

     public class MyThread extends Thread{ 
     	@Override 
     	public void run() { 
     		for (int i=1;i<=10;i++){
      			System.out.println(i); 
     		 } 
     	 } 
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    测试类

    
    public class Testhuang {
        public static void main(String[] args) {
            //实例化对象
            MyThread myThread = new MyThread();
            myThread.start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    输出结果:
    在这里插入图片描述

    4.2第二种 实现Runnable接口

    步骤:

    1.定义一个类 实现 Runnable
    2.实现run()
    3.实例化线程对象 Thread 传递一个参数 Runnable 的实现类
    4.调用方法开启线程 start()

    线程定义类

    public class MyRunnable implements Runnable {
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    测试类

    public class Testhuang {
        public static void main(String[] args) {
            //实例化Runnable对象的实现类
          MyRunnable r = new MyRunnable(); //实例化线程类
            Thread th = new Thread(r); //开启线程
             th.start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果
    在这里插入图片描述

    4.3第三种 实现Callable接口

    步骤

    1.定义一个类实现接口 Callable
    2.重写call()方法
    3.实例化 任务对象 FutureTask 构建一个Callable的实现类
    4.实例化线程对象 Thread 构建一个任务对象
    5.开启线程
    6.调用任务对象的get() 获取其返回值

    实现线程类

    public class MyCallAble implements Callable {
        @Override
        public Integer call() throws Exception {
            Integer sum = 0;
            for (int i = 0; i <= 100; i++) {
                sum += i;
            }
            return sum;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    测试类

    public class Testhuang {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            MyCallAble call = new MyCallAble();
            FutureTask f = new FutureTask<>(call);
            Thread t = new Thread(f);
            t.start();
            Integer c = f.get();
            System.out.println(c);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    结果
    在这里插入图片描述

    4.4 最常用的创建线程的方式

    使用Runnable的匿名内部类来创建线程

    public class Testhuang {
        public static void main(String[] args) { 
            //第一种方式
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            }).start();
            
            
            //第二种方式
            new  Thread(){
                @Override
                public  void  run(){
                    System.out.println(Thread.currentThread().getName());
                }
            }.start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    结果
    在这里插入图片描述

    4.5 线程调度的方式

    线程调度的方式有两种

    1.分配式调度:多个线程执行任务的时间,都是评价分配,每一个线程执行的周期都是相同的
    2.抢占式调度:线程的优先级越高,获取cpu执行权越高,线程抢到cpu的概率就越搞,优先执行的概率就越高,而我们的java中的多线程就是抢占式调度

    在这里插入图片描述

    例子:
    创建线程类

    public class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 1; i <= 10; i++) {
                try {
                    //sleep方法是休眠方法,这里间隔0.1s
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //.getName方法获取当前线程的名称
                System.out.println(Thread.currentThread().getName() + "\t" + i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    测试类:

    public class Testhuang {
        public static void main(String[] args) {
            //开启第一个线程
            MyThread th1 = new MyThread();
            th1.start();
    
            //开启第二个线程
            MyThread th2 = new MyThread();
            System.out.println(th2);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    4.5线程的内存图

    在这里插入图片描述

    4.7 线程的常见方法

    4.7.1 获取线程名

    方法名作用
    public final String getName()返回该线程的名称
    public static Thread currentThread()返回对当前正在执行的线程对象的引用

    线程创建类

    public class MyThread extends Thread {
        @Override
        public  void  run(){
            for (int i = 0; i < 10; i++) {
                System.out.println(getName() + "\t" + i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    测试类

    public class Testhuang {
        public static void main(String[] args) {
            //实例化线程对象
            MyThread th = new MyThread();
            th.start();
            for (int i = 1; i <= 10; i++) {
               System.out.println(Thread.currentThread().getName() + "\t" + i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果
    在这里插入图片描述

    4.7.2 线程休眠

    方法名作用
    public static void sleep(long millis)线程休眠

    线程创建类

    public class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 60; i >= 1; i--) {
                System.out.println("还剩下" + i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    测试类

    public class Testhuang {
        public static void main(String[] args) {
            //实例化线程对象
            MyThread th = new MyThread();
            th.start();
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果

    在这里插入图片描述

    4.7.3 守护线程

    方法名作用
    public final void setDaemon(boolean on)设置为守护线程
    public final boolean isDaemon()测试该线程是否为守护线程

    线程创建类

    public class MyThread extends Thread {
        @Override
        public void run() {
            try {
                //休眠五秒
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                OutputStream is = new FileOutputStream("3.txt");
                is.write(97);
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    测试类

    public class Testhuang {
        public static void main(String[] args) {
            //实例化线程对象 
            MyThread my = new MyThread();
            //设置为守护线程 
            my.setDaemon(true);
            //获取其状态 
            System.out.println(my.isDaemon());
            my.start();
            try {
                Thread.sleep(6000);
            } catch (
                    InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    结果

    显示开启了守护线程

    4.7.4 设置线程的优先级

    4.7.4.1 常量

    常量名作用
    public static final int MAX_PRIORITY线程可以具有的最高优先级
    public static final int MIN_PRIORITY线程可以具有的最低优先级
    public static final int NORM_PRIORITY分配给线程的默认优先级

    在这里插入图片描述
    注意点

    1.线程的最高优先级10最低优先级1,范围1-10
    2.线程优先级越高表示获取cpu执行权越大即被执行的概率越高,但是并不一定会执行 ,因为java是抢占式调度

    4.7.4.2 方法

    方法名作用
    public final int getPriority()返回的是线程的优先级
    public final void setPriority(int newPriority)更改线程的优先级

    线程创建类

    public class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 1; i <= 100; i++) {
                System.out.println(getName() + "\t" + i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    测试类

    public class Testhuang {
        public static void main(String[] args) {
            //实例化第一个线程
            MyThread t = new MyThread();
            t.setPriority(8);
            t.start(); //
            // 实例化第二个线程
            MyThread th = new MyThread();
            th.setPriority(Thread.MAX_PRIORITY);
            th.start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果
    在这里插入图片描述

  • 相关阅读:
    Linux远程管理工具
    KINODYNAMIC-路径规划
    Mysql数据库基础:DML数据操作语言
    Java学习 --- 面向对象之继承
    深度学习(四)——torchvision中数据集的使用
    Java Collections singletonList()方法具有什么功能呢?
    USB连接与检测
    【毕业设计】单片机(stm32)远程智能宠物喂养系统 - 物联网 esp8266
    释放数字生产力 引领数字化转型新纪元——弘玑Cyclone 2022产品发布会圆满落幕
    springboot爱护大自然的设计与实现毕业设计源码231643
  • 原文地址:https://blog.csdn.net/weixin_43189971/article/details/126096649