Java多线程

文章介绍了进程和线程的概念,以及多线程在提高效率和用户体验上的优势。通过示例展示了如何在Java中创建线程,包括继承Thread类和实现Runnable接口两种方式,并比较了它们的区别。还通过售票模拟展示了线程同步的重要性,以及如何避免死锁。最后提到了守护线程和线程状态,以及同步机制Synchronized的作用。
摘要由CSDN通过智能技术生成

进程

正在运行的一个程序

线程

在一个进程中,执行一套功能流程,称为线程
在一个进程中,执行多套功能流程,称为多线程

为什么使用多线程

抢占式策略系统:系统会为每个执行任务的线程分配一个很小的时间段,当该时间段使用完后,系统会强制的夺其cpu执行权交给其他线程完成任务
①可以提高效率
②增强用户体验

创建执行线程的方式

①声明一个类继承Thread类
②重写Thread类的run()方法,同时编写线程执行体
③创建该子类的实例
④通过start()启动线程,默认run()方法

 public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();
        //当前电脑cpu数量
        int cpuNums = runtime.availableProcessors();
        System.out.println(cpuNums);
    }
public class ThreadTest01 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.start();//最终会执行cat的run()方法
    }
}
class Cat extends Thread{
    int count=0;
    //重写run方法
    @Override
    public void run() {
        while (true) {
            //该线程每间隔一秒,输出一次
            System.out.println("yhf 天下第一"+(++count)+"线程名"+Thread.currentThread().getName());
            //让线程休眠1秒
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(count==80){
                break;//=80退出
            }
        }
    }
}

通过实现接口Runnable来开发线程

public static void main(String[] args) {
        Dog dog = new Dog();
        //dog.start();这里不能调用start
        Thread thread = new Thread(dog);
        thread.start();
    }
}
class Dog implements Runnable{
}

继承Thread和实现Runnable的区别

①通过继承Thread或者实现Runnable接口来创建线程本质上没有区别,底层都是start()->start0()
②实现Runnable接口方式更加适合多个线程共享一个资源的情况,并且避免了单继承的限制

模拟售票

方式一(超卖)

public static void main(String[] args) {
        /*模拟三个窗口*/
        SellTicket01 s1 = new SellTicket01();
        SellTicket01 s2 = new SellTicket01();
        SellTicket01 s3 = new SellTicket01();
        s1.start();
        s2.start();
        s3.start();
    }
}
class SellTicket01 extends Thread{
    private static int TicketNum=100;//三个线程共享

    @Override
    public void run() {
        while (true){
            if (TicketNum<0){
                System.out.println("售票结束");
                break;
            }
            try {
                //休眠50毫秒
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口"+Thread.currentThread().getName()
                    +"售出一张票"+"剩余票数"+(--TicketNum));
        }
    }
}

方式二(超卖)

public static void main(String[] args) {
        SellTicket02 s1 = new SellTicket02();
        SellTicket02 s2 = new SellTicket02();
        SellTicket02 s3 = new SellTicket02();
        new Thread(s1).start();
        new Thread(s2).start();
        new Thread(s3).start();
    }
}
class SellTicket02 implements Runnable{
    private static int TicketNum=100;//三个线程共享

    @Override
    public void run() {
        while (true){
            if (TicketNum<0){
                System.out.println("售票结束");
                break;
            }
            try {
                //休眠50毫秒
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口"+Thread.currentThread().getName()
                    +"售出一张票"+"剩余票数"+(--TicketNum));
        }
    }
}

线程终止

设置一个控制变量,通过set方法修改值
在这里插入图片描述

线程常用方法

在这里插入图片描述

线程插队

在这里插入图片描述

守护线程和用户线程

①用户线程,也叫工作线程
②守护线程:一般是为工作线程服务的,当所有用户线程结束时,守护线程自动结束
③常见的守护线程:垃圾回收机制

在这里插入图片描述

线程的状态

在这里插入图片描述

在这里插入图片描述

同步机制Synchronized

不允许多个线程同时访问一个数据
在这里插入图片描述

互斥锁

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

死锁

多个线程都占用了对方的锁资源,但不肯相让,导致死锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ChinaJDK

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

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

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

打赏作者

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

抵扣说明:

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

余额充值