java多线程

1,java多线程入门

1.1,进程

是正在运行的程序

  • 是系统进行资源分配和调用的独立单位

  • 每一个进程都有它自己的内存空间和系统资源

1.2,线程

是进程中的单个顺序控制流,是一条执行路径。

  • 单线程:一个进程如果只有一条执行路径,则称为单线程程序

  • 多线程:一个进程若果有多条执行路径,则称为多线程程序。

1.3,多线程的实现方式

1.3.1,继承Thread

// 1,继承Thread
public class TextThread extends Thread {

    // 2,重写run方法
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("我是run");
        }
    }

    public static void main(String[] args) {
        // 3,创建线程实例对象
        TextThread textThread = new TextThread();
        // 4,调用start方法
        textThread.start();

        for (int i = 0; i < 20; i++) {
            System.out.println("我是main");
        }
    }
}
  • 继承Thread
  • 重写run方法
  • 创建线程实例对象
  • 调用start方法

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

start():启动线程,然后由JVM调用此线程的run()方法

1.3.2,实现Runnable接口

// 1,实现Runnable接口
public class TextThread implements Runnable {
    // 2,重写run方法
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("我是run");
        }
    }
    public static void main(String[] args) {
        // 3,创建Runnable接口的实现类对象
        TextThread textThread = new TextThread();
        // 4, 创建线程实例对象
        // 可以给线程起名字
        Thread thread = new Thread(textThread);
        // 5,调用start方法
        // new Thread(textThread).start()
        thread.start();

        for (int i = 0; i < 20; i++) {
            System.out.println("我是main");
        }
    }
}
  • 实现Runnable接口
  • 重写run方法
  • 创建Runnable接口的实现类对象
  • 创建线程实例对象
  • 调用start方法

1.3.3,实现Callable接口

import java.util.concurrent.*;

// 实现Callable接口
public class TextCallable implements Callable<Boolean> {
    // 重写call方法
    @Override
    public Boolean call() {
        return true;
    }
    public static void main(String[] args) {
        // 创建对象
        TextCallable t1 = new TextCallable();
        // 创建执行服务
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        // 提交执行
        Future<Boolean> submit1 = executorService.submit(t1);
        Future<Boolean> submit2 = executorService.submit(t1);
        Future<Boolean> submit3 = executorService.submit(t1);

        // 获取结果
        try {
            boolean r1 = submit1.get();
            boolean r2 = submit2.get();
            boolean r3 = submit3.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // 关闭服务
        executorService.shutdownNow();
    }
}
  • 实现Callable接口
  • 重写call方法
  • 创建对象
  • 创建执行服务
  • 提交执行
  • 获取结果
  • 关闭服务

1.3.4,知识卡片

静态代理:

  • 目标对象和代理对象都要实现同一个接口
  • 代理对象中有目标对象的入口

优点

  • 目标对象专注于做自己的事情,其他都交给代理对象

案例:模拟龟兔赛跑

public class Race implements Runnable {
    private static String winner;
    @Override
    public void run() {
        for(int i = 0;i <= 100;i++) {
            boolean flag = gameOver(i);
            if (flag) {
                break;
            }
             System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
        }
    }
    public boolean gameOver(int steps) {
        if(winner != null) {
            return true;
        }
        if (steps == 100) {
            winner = Thread.currentThread().getName();
            System.out.println("winner is"+winner);
            return true;
        }
        return false;
    }
    
    public static void main(String[] args) {
        Race race = new Race();
        new Thread(race,"兔子").start();
        new Thread(race,"乌龟").start();
    }
}

1.4,设置和获取线程的名称

获取线程名称:getName()方法

设置线程名称:setName()方法

currentThread():返回当前正在执行的线程对象的引用

1.5,线程生命周期

在这里插入图片描述

  • 不要用JDK的方法停止线程
  • 最好是线程自己停下来
  • 建议使用一个标志位停止线程

sleep()方法:是当前正在执行的线程暂缓执行

  • 可以模拟网络延时,放大问题的发生性,检查代码
  • 模拟倒计时
  • 打印当前系统时间

yield()方法:让CPU重新调度线程

join()方法:让线程强制执行,执行完后,在执行其他线程

1.6,线程优先级

getPriority()方法:返回此线程的优先级

setPriority()方法:设置此线程优先级,范围是1-10

1.7,用户线程和守护线程

虚拟机必须保证用户线程执行完毕

虚拟机不必保证守护线程执行完毕

setDaemon():将线程设置为守护线程

1.8,线程同步

并发:同一个对象被多个线程同时操作,会有并发问题

同步方法

public synchronized void method() {
    
}

同步方法控制对对象的访问,每一个对象对应着一把锁,每个同步方法都必须获得调用该方法的对象的锁才能执行,否则线程会阻塞,方法一旦执行,就独占该锁,直到该方法返回才释放锁,后面被阻塞的线程才能获得这个锁,继续执行,解决并发问题

缺陷:效率下降

同步块

synchronized(Obj) {
    
}

Obj:称之为 同步监视器

  • Obj 可以是任意对象,但是推荐使用共享资源作为Obj
  • 同步方法的锁是this

同步监视器的执行过程

  1. 第一个线程访问,锁定同步监视器,执行其中代码
  2. 第二个线程访问,发现同步监视器被锁定,无法访问
  3. 第一个线程访问完毕,释放锁
  4. 第二个线程访问,发现同步监视器没锁,然后锁定并访问

1.9,死锁

两个对象都希望获得对方的锁而互相僵持导致死锁

1.10,Lock锁

jdk5开始,提供了更加强大的线程同步机制,通过显示定义同步锁对对象实现同步,同步锁使用Lock对象充当

ReentrantLock类实现了Lock,比较常用

1.11,线程池

ExecutorService和Executors

可以参考JDK帮助文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

草莓小子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值