java_进阶:线程

1、进程、线程 和 程序

  • 程序: 是为了完成特定任务 用某种语言编写的一组指令的集合。指的一段静态。

  • 进程:是程序的一次执行过程,或是正在运行的一个程序,是一个动态的过程:有他自身的产生 存在 以及消亡的过程–生命周期

程序是静态的 进程是动态的。进程作为资源分配单位,系统在运行时会为每个进程分配不同的内存区域。

  • 线程(thread) 进程进一步细化就是线程,是一个程序内部的一条执行路径。

若一个进程同一时间并行执行多个线程,就是支持多线程。

线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器,线程的切换开销比较小

2、单核CPU和多核CPU

在java中 一个程序至少有三个线程组成, 主线程(main) 垃圾回收线程(gc) 异常处理线程。

并行和并发:

  • 并行:多个CPU同时执行多个任务
  • 并发: 一个CPU在同一时刻,同时处理多个任务。

3、使用多线程的优点:

  1. 提高了应用程序的响应。

  2. 提高了计算机CPU的利用率

  3. 改善程序结构。

4、何时需要多线程?

  • 程序需要同时执行两个或多个任务
  • 程序需要实现一些需要等待的任务的时候:如:用户输入,文件读写 网络操作等。
  • 需要一些后台运行的程序时

5、实现多线程

5.1 继承 Thread类

//自定义了一个线程类
public class MyThread extends  Thread{
    @Override
    public void run() {
        for(int i = 0 ; i < 100 ;i++){
            System.out.println(i);
        }
    }
}
    public static void main(String[] args) {
//        创建了两个线程
        Thread t1 = new MyThread();
        Thread t2 = new MyThread();
//        t1.run();//调用线程的run方法  不属于多线程
//        t2.run();
       // start() 导致此线程开始执行; Java虚拟机调用此线程的run方法。
        t1.start();//启动线程
        t2.start();
    }

为什么要重写run方法?

​ 因为run方法是用来封装被线程执行的代码的。

run方和start方法的区别?

​ run()封装了线程执行的代码,直接调用的,相当于普通方法调用。

​ start方法 启动线程,然后由jvm调用此线程的run方法

   Thread t3 = new Thread(){
            @Override
            public void run() {
                System.out.println("创建线程 ");
            }
   };

5.2 实现 Runnable 接口

Runnable接口应由任何类实现,其实例将由线程执行。 该类必须定义一个无参数的方法,称为run

public class MyRannable  implements  Runnable{
    @Override
    public void run() {
        for (int i= 0 ; i < 1000 ; i ++){
            System.out.println(i);
        }
    }
}
public class MyRunnableTest {
    public static void main(String[] args) {
        Runnable r = new MyRannable();
        Thread t1 = new Thread(r);//线程负责执行Runnable接口的方法
        Thread t2 = new Thread(r);
        //启动线程
        t1.start();
        t2.start();
    }
}

// 另一种写法
         new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程创建");
            }
        }).start();

6、设置和获取线程的名称

  • Thread(String name) 分配一个新的 Thread对象。
voidsetName(String name) 将此线程的名称更改为等于参数 name
voidsetName(String name) 将此线程的名称更改为等于参数 name
static ThreadcurrentThread() 返回对当前正在执行的线程对象的引用。
public class MyRunnableTest {
    public static void main(String[] args) {
        Runnable r = new MyRannable();
        Thread t1 = new Thread(r,"线程001");//线程负责执行Runnable接口的方法
        Thread t2 = new Thread(r);
        t2.setName("线程002");
        //Thread t3 = new Thread(new Runnable() {
         new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程创建");
            }
        },"线程003").start();//设置线程名称
        //t3.start();
        //启动线程
        t1.start();
        t2.start();
        System.out.println(Thread.currentThread().getName());//获取系统当前正在执行的线程
    }
}

public class MyRannable  implements  Runnable{
    @Override
    public void run() {
        for (int i= 0 ; i < 1000 ; i ++){
            System.out.println(Thread.currentThread().getName()+"------------->"+i);
        }
    }
}

7、线程的优先级

intgetPriority() 返回此线程的优先级。
voidsetPriority(int newPriority) 更改此线程的优先级。
  • 每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行

线程的两种调度模型

​ 分时调度: 所有线程轮流实现CPU的使用权,平均分配每个线程占有CPU的时间片

​ 抢占式调度: 优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个。优先级高的线程获得CPU执行权的概率更高。

java是的是抢占式的调度模型。
线程的默认优先级为5,线程的优先级的范围为1–10

8、线程控制

voidjoin() 等待这个线程死亡
voidsetDaemon(boolean on) 将此线程标记为 daemon线程或用户线程。
static voidsleep(long millis) 使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。

9、线程的分类

线程分为:守护线程 用户线程

  • 守护线程和用户线程基本上是相同的,唯一区别就是判断JVM何时离开
  • 守护线程是用来服务用户线程的。通过在start方法之前调用thread.setDaemon(true) 可以将一个用户线程变成守护线程
  • java的垃圾回收 他是一个典型的守护线程
  • 如果JVM中都是守护线程,JVM将退出(用户线程执行结束 守护线程无论是否结束 都将终止执行)

10、线程的生命周期

线程的状态通常分为5种状态:

​ 新建(NEW):当一个Thread类及其子类的对象被声明并创建时,此时的线程对象就处于新建状态

​ 就绪 (WAITING | TIMED_WAITING): 处于新建状态的线程被start后,线程将进入CPU的执行队列等待获得CPU的执行权,此时的线程已经具备了运行的条件,只是还未获得CPU的执行权

运行(RUNNABLE):当就绪的线程获得CPU的执行权 ,处于运行状态

​ 阻塞(BLOCKED):在某种特殊的情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执行。此时线程就进入阻塞状态

​ 死亡(TERMINATED):线程完成了他的全部工作或被线程被提前强制性的终止 或出现异常导致线程异常结束。

线程状态之间的转换
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值