多线程(一)概念、线程

多线程(一)概念、线程

目录

进程、线程、程序

  • 进程
    • 一个进程可以有多个线程(如视频中听声音,看图像,看弹幕)
    • 进程程序执行的过程
    • 进程是系统资源分配的单位
    • 一个进程至少有一个线程
    • 线程是cpu调度和执行的单位
  • 线程
    • 线程是独立执行的概念

进程

进程创建(三种方式)

方式1:Thread class(重点)
  • 继承Thread类
步骤:
  • 自定义线程类继承Thread类
  • 重写run()方法,编写线程执行体
  • 创建线程对象,调用start()方法启动线程
代码实例(创建进程)
//线程开启不一定执行,由cpu调度执行
public class TestThread01 extends Thread{
    //线程的执行体
    public void run(){
        //run方法线程体
        for(int i=0;i<20;i++){
            System.out.println("sxp01:"+i);
        }
    }
    public static void main(String[] args) {
        //主线程
        //创建一个线程对象
        TestThread01 testThread01=new TestThread01();
        //调用start()方法开启线程
        testThread01.start();
        for(int i=0;i<20;i++){
            System.out.println("sxp02:"+i);
        }
    }
}
//输出:
sxp02:0
sxp02:1
sxp02:2
sxp02:3
sxp01:0
sxp02:4
sxp02:5
sxp02:6
sxp02:7
sxp01:1
sxp02:8
sxp01:2
sxp02:9
sxp01:3
sxp02:10
sxp01:4
sxp02:11
sxp01:5
sxp02:12
sxp01:6
sxp01:7
sxp01:8
sxp02:13
sxp01:9
sxp02:14
sxp01:10
sxp01:11
sxp02:15
sxp01:12
sxp02:16
sxp01:13
sxp02:17
sxp02:18
sxp02:19
sxp01:14
sxp01:15
sxp01:16
sxp01:17
sxp01:18
sxp01:19
方式2:Runnable接口(重点)(推荐)
  • 实现Runnable接口
步骤:
  • 实现Runnable接口
  • 重写run()方法,编写线程执行体
  • 启动线程:传入目标对象+Thread对象.start()
  • 推荐使用:避免单继承的局限性,方便同一个对象被多个线程使用
代码实例(创建进程)
//创建线程方式2
public class TestThread02 implements Runnable{
    //run方法线程体
    public void run(){
        for(int i=0;i<20;i++){
            System.out.println("sxp01:"+i);
        }
    }
    public static void main(String[] args) {
        //主线程
        //创建一个线程对象
        TestThread02 testThread02=new TestThread02();
        //创建线程对象,通过线程对象来开启我们的线程,代理
        Thread thread=new Thread(testThread02);
        thread.start();
        for(int i=0;i<20;i++){
            System.out.println("sxp02:"+i);
        }
    }
}
//输出:
sxp01:0
sxp02:0
sxp02:1
sxp02:2
sxp02:3
sxp01:1
sxp02:4
sxp02:5
sxp01:2
sxp01:3
sxp01:4
sxp01:5
sxp02:6
sxp01:6
sxp01:7
sxp01:8
sxp01:9
sxp02:7
sxp01:10
sxp01:11
sxp02:8
sxp02:9
sxp01:12
sxp01:13
sxp01:14
sxp01:15
sxp01:16
sxp01:17
sxp01:18
sxp01:19
sxp02:10
sxp02:11
sxp02:12
sxp02:13
sxp02:14
sxp02:15
sxp02:16
sxp02:17
sxp02:18
sxp02:19
多线程操作同一个对象(买票)
  • 本次代码是有问题的 ,多个线程操作同一个资源,线程不安全,数据紊乱
//多个线程同时操作同一个对象
//多个线程操作同一个资源,线程不安全,数据紊乱
public class TestThread03 implements Runnable{
    //票数
    //被调整的资源
    private int ticketNums=10;
    @Override
    public void run() {
        while (true){
            if (ticketNums<=0) {
                break;
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"张票");
        }
    }

    public static void main(String[] args) {
        TestThread03 testThread03=new TestThread03();
        //同一对象(都是testThread03),操控的ticketNums是同一个
        new Thread(testThread03,"小明").start();
        new Thread(testThread03,"老师").start();
        new Thread(testThread03,"黄牛").start();
    }
}
//输出:
黄牛拿到了第8张票
小明拿到了第9张票
老师拿到了第10张票
黄牛拿到了第6张票
老师拿到了第5张票
小明拿到了第7张票
小明拿到了第2张票
小明拿到了第1张票
老师拿到了第3张票
黄牛拿到了第4张票
模拟龟兔赛跑
//模拟龟兔赛跑
public class TestThread04 implements Runnable{
    private static String winner;
    @Override
    public void run() {
        for(int i=0;i<=100;i++){
            //模拟兔子休息
            if(Thread.currentThread().getName().equals("兔子") && i%10==0){
                try {
                    Thread.sleep(3);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            //判断比赛是否结束
            boolean flag=gameOver(i);
            if(flag){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");
        }
    }
    //判断是否完成比赛
    private boolean gameOver(int steps){
        //判断是否有胜利者
        if(winner!=null){//已经存在胜利者了
            return true;
        }else {
            if (steps>=100){
                winner=Thread.currentThread().getName();
                System.out.println("胜利者是"+winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        TestThread04 testThread04=new TestThread04();
        new Thread(testThread04,"兔子").start();
        new Thread(testThread04,"乌龟").start();
    }
}
方式3:Callable接口(了解)
  • 实现Callable接口
  • 需要返回值类型
  • 重写call方法,需要抛出异常
上一篇:Thales Sentinel LDK Run-Time Environment输入验证错误漏洞


下一篇:electron + vue 从搭建 运行 到打包