2021-07-22

多线程

  1. 线程的创建和开启

  2. 线程的状态,新生、就绪、运行、阻塞、终止

  3. 线程安全

Thread类

​ 1.进程:系统中的应用程序,具有自己的资源,内存空间,是系统运行的基本单位,一个进程包含1~n个线程。

​ 2.线程:多个线程共享一个进程的资源和数据空间,每一个线程具有自己的程序计数器,线程是CPU调度的最小单位。

线程的创建

  1. 继承Thread ,重写run()方法,定义线程体;

  2. 实现Runnable接口,重写run()方法;

  3. juc包下Callable接口,重写call()方法

    实现Callable,重写call,在方法内部定义线程体(线程池)

    a.call可以抛出异常

    b.可以定义返回值

    注:

    1. 类是单继承,接口是多实现
    2. 可以实现资源共享

练习:

1、模拟购票–>100张票,三个人买完

package com.yjx.thread;

public class Class03_web12306 implements Runnable{
     static int  ticket=100;

    @Override
    public void run() {
        while (true){
            if(ticket<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"正在买第"+ticket--+"张票");
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Class03_web12306 web=new Class03_web12306();
        Thread th1=new Thread(web,"张三");
        Thread th2=new Thread(web,"李四");
        Thread th3=new Thread(web,"王五");
        th1.start();
        th2.start();
        th3.start();
    }
}

2.网络图片下载

package com.yjx.thread;

import java.io.File;
import org.apache.commons.io.FileUtils;

import java.io.*;
import java.net.URL;

public class Practice1 {
    public static void main(String[] args) {
        Thread th1=new Thread(new DownHtml("https://p4.img.cctvpic.com/photoworkspace/2021/07/22/2021072211110642797.jpg","src\\one.jpg"));
        Thread th2=new Thread(new DownHtml("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","src\\two.png"));
        Thread th3=new Thread(new DownHtml("https://p3.img.cctvpic.com/photoAlbum/page/performance/img/2021/7/22/1626946753175_318.jpg","src\\three.jpg"));
        th1.start();
        th2.start();
        th3.start();
    }

}

class DownHtml implements Runnable{
    private String url;
    private String path;

    public DownHtml(String url, String path) {
        this.url = url;
        this.path = path;
    }

    @Override
    public void run() {
        Down.down(url,path);
    }
}

class Down{
    public static void down(String url,String path){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(path));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

3.模拟龟兔赛跑

package com.yjx.thread;

public class Practice2 implements Runnable{
    private static String winner=null;

    @Override
    public void run() {
        for (int step=1;step<=100;step++){
            System.out.println(Thread.currentThread().getName()+"正在跑第"+step+"步");
            if(step%10==0 && "兔子".equals(Thread.currentThread().getName())){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (checkwinner(step)){
                break;
            }
        }

    }

    private boolean checkwinner(int step) {
        if(winner!=null){
            return true;
        }
        if(step==100){
            winner=Thread.currentThread().getName();
            System.out.println(Thread.currentThread().getName()+"赢了");
            return true;
        }

        return false;
    }


    public static void main(String[] args) {
        Practice2 bisai=new Practice2();
        Thread th1=new Thread(bisai,"兔子");
        Thread th2=new Thread(bisai,"乌龟");
        th1.start();
        th2.start();

    }
}

线程状态

新生状态:new Thread,当前线程处于新生状态。

就绪状态:start(),这个线程进入就绪状态,线程准备好可以被CPU调度,会进 入就绪队列,等待CPU调度

运行状态:当CPU调度到这个线程,线程进入到运行状态开始执行。

阻塞状态:当程序无法正常执行,(进入阻塞状态有多种方式)

终止状态:线程结束

  1. 一个线程一旦终止,无法恢复

  2. 阻塞状态,阻塞解除会直接恢复就绪状态

    进入阻塞状态的几种方式:sleep() 、join()、wait()、IO

    进入就绪状态的几种方式:start()、yield()、线程切换、阻塞解除

    进入终止状态的几种方式:stop(已过时)、正常执行完毕、添加标识 判断

  3. 操作线程的常用方法:

    sleep():1.模拟网络延迟

    ​ 2.模拟方法问题的可能性

    yield():礼让线程,当一个线程调用yield,让出CPU的资源,进入到就绪状态

    join():插队线程,可指定插队的时间(先就绪,后插队)

    interrupt():主线程添加一个中断标识。

    isInterrupt():测试此线程是否已被中断,是否调用过interrupt()方法添加中断 标识

    interrupted():测试此线程是否已被中断,是否调用过interrupt()方法添加中 断标识,同时会复位标识 。

    ​ (一个线程如果终止,中断标识 也会复位)

    getState():获取当前线程的状态

    1. NEW
    2. RUNNABLE
    3. BLOCKED
    4. WAITING
    5. TIMED_WAITING
    6. TERMINATED

    Priority线程的优先级

    线程的优先级越高,执行的可能性就越大

    1~10优先级的数值范围,默认5

setPriority()设置优先级

getPriority()获取优先级

守护线程

通常用户创建的线程默认是用户线程,守护线程是用来守护用户线程,当程序中所有的用户线程全部执行完毕,守护线程会直接结束

setDaeson(true)设置守护线程

isDaeson()判断线程是否为守护线程

注:java中的垃圾回收机制就是一个典型的守护线程

线程安全问题

多线程同时操作同一份资源才有可能遇到线程不安全问题

同步锁:让关键重点代码排队执行,其他代码依旧同时执行,在提高效率的基础 上保证数据安全。

synchronized 关键字

关注点:

  1. 限制条件:对象锁【每个对象只有一把锁】

  2. 同步的代码范围

    范围大 效率低

    范围小 锁不住

  3. 使用方式:

    同步方法

    同步块

锁的对象:this,类(类的class对象),资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值