Java入门Day13:线程

  • 程序program
    完成特定任务,用语言编写的一组指令的集合。
  • 进程
    1.进程是运行中的程序,启动一个程序,操作系统会为进程分配内存空间。
    2.进程是程序的异常执行过程,进行中的程序,是动态过程,它有自己的产生、存在和消亡的过程。

1. 线程

1.线程是由进程创建的,它是进程的实体。
2.一个进程可以拥有多个线程。
3.线程也可以拥有线程。
4.线程有自己的生命周期。

1.1 单线程

同一个时刻,只允许执行一个线程。

1.2 多线程

同一个时刻,可以执行多个线程。

1.3 线程的基本使用

  • 继承Thread类,重写run方法
  • 实现Runnable接口,重写run方法

1.4 Thread 类

Thread的start方法开启了一个子线程:Thread0,主线程不会阻塞,会继续执行
它的底层是调用了start调用了start0方法,start0方法调用Java底层的C/C++代码,创建了新的线程
start0还会调用重写的run方法,在新的线程中运行

/*
继承Thread类,重写run方法
 */

public class Demo01{
    public static void main(String[] args) {
        Mouse mouse = new Mouse();
        mouse.start();

    }
}
class Mouse extends Thread{
    @Override
    public void run() {
        int times = 0;
        while (true){
            System.out.println("鼠鼠过街,吱吱~");
            times++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (times==10){
                break;
            }
        }
    }
}

1.5 Runnable 接口

因为类只能单继承,有点类以及继承了其他类,无法继承Thread类,可以实现Runnable接口
Runnable接口中只有run方法,而没有start方法,所以需要通过建立Thread的对象接收类对象(Thread中有一个Runnable类型的属性,可以接收实现了Runnable接口的对象)
来调用Thread的start方法,这是一种设计模式(静态代理)。

public class Demo02 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Thread thread = new Thread(dog);
        thread.start();

    }
}
class Dog implements Runnable{
    @Override
    public void run() {
        int times = 0;
        while (true){
            System.out.println("大黄狗,汪汪叫");
            times++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (times==10){
                break;
            }
        }
    }
}

例子

public class Demo03 {
    public static void main(String[] args) {
        Tiger tiger = new Tiger();
        Bird bird = new Bird();
        new Thread(tiger).start();
        new Thread(bird).start();
    }
}
class Tiger implements Runnable{
    @Override
    public void run() {
        int times = 0;
        while (true){
            System.out.println("大老虎,嗷嗷叫");
            times++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (times==10){
                break;
            }
        }
    }
}
class Bird implements Runnable{
    @Override
    public void run() {
        int times = 0;
        while (true){
            System.out.println("小鸟,叽叽叽~");
            times++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (times==5){
                break;
            }
        }
    }
}

1.6 售票问题

public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        Ticket1 ticket1 = new Ticket1(1000);
        Ticket1 ticket2 = new Ticket1(1000);
        Ticket1 ticket3 = new Ticket1(1000);
        new Thread(ticket1).start();
        new Thread(ticket2).start();
        new Thread(ticket3).start();
        Thread.sleep(3*1000);
    }
}
class Ticket1 implements Runnable {
    private static int num = 100;
    private int sleep;


    public Ticket1(int sleep) {
        this.sleep = sleep;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            num--;
            System.out.println(Thread.currentThread().getName()+"窗口售出:"+"剩余票数:"+num);
            if (num <= 0) {
                System.out.println("售完");
                break;
            }
        }
    }
}

售票员可能会多卖出1-2张票,这是因为当票售完时,某个售票员已经进入了售票过程,也就是循环体中。这时就会多卖票。
这是因为Thread和Runnable是线程不安全的。

1.7 线程终止

我们可以通过在类的属性中加入一个flag,再通过对flag进行控制,来控制线程的终止。


public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        Ticket1 ticket1 = new Ticket1(1000);
        Ticket1 ticket2 = new Ticket1(1000);
        Ticket1 ticket3 = new Ticket1(1000);
        new Thread(ticket1).start();
        new Thread(ticket2).start();
        new Thread(ticket3).start();
        Thread.sleep(3*1000);
        ticket1.setLoop(false);
        ticket2.setLoop(false);
        ticket3.setLoop(false);
    }
}
class Ticket1 implements Runnable {
    private static int num = 100;
    private int sleep;
    private boolean loop = true;

    public boolean isLoop() {
        return loop;
    }

    public void setLoop(boolean loop) {
        this.loop = loop;
    }

    public Ticket1(int sleep) {
        this.sleep = sleep;
    }

    @Override
    public void run() {
        while (loop) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            num--;
            System.out.println(Thread.currentThread().getName()+"窗口售出:"+"剩余票数:"+num);
            if (num <= 0) {
                System.out.println("售完");
                break;
            }
        }
    }
}

2. 并发和并行

2.1 并发

同一时刻,多个任务交替执行,造成一种"同时“的错觉,这是因为单核cpu的效率高。
简单说,单核cpu实现多任务就是并发。

2.2 并行

同一时刻,多个任务同时执行,多喝cpu可以实现并行。

3. 线程常用方法

1.setName //设置线程名称,使之与参数name相同
2.getName //返回该线程的名称
3.start //使该线程开始执行;Java虚拟机底层调用该线程的start()方法
4.run //调用线程对象run方法
5.setPriority //更改线程的优先级
6.getPriority //获取线程的优先级
7.sleep //在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
8.interrupt //中断线程的优先级

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值