Day17_进程(上)

Day17_进程(上)

创建线程

第一种方式:继承Thread类

//普通类想要具备多线程的能力,继承Thread类
//线程类
public class Demo01 extends Thread {
    @Override
    //线程体--以后要争抢资源做的事
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println("Demo01---"+i);
        }
    }
}
public class test {
    public static void main(String[] args) {
        for (int i = 1; i <= 5; i++) {
            System.out.println("main01---"+i);
        }
        Demo01 tt=new Demo01();
        tt.start();//线程的启动
        for (int i = 1; i <= 5; i++) {
            System.out.println("main02---"+i);
        }
    }
}

输出结果:

main01---1
main01---2
main01---3
main01---4
main01---5
main02---1
main02---2
main02---3
Demo01---1
main02---4
main02---5
Demo01---2
Demo01---3
Demo01---4
Demo01---5

设置读取线程名称

第一种方式:使用setName()设置线程名称

public class test01 {
    public static void main(String[] args) {
        Thread.currentThread().setName("The main---");
        Demo01 tt=new Demo01();
        tt.setName("Demo01");
        tt.start();//线程的启动
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}

输出:

Demo011
The main---1
Demo012
The main---2
Demo013
Demo014
Demo015
The main---3
The main---4
The main---5

第二种方式:使用构造器设置线程名称

public class Demo02 extends Thread {
    public Demo02(String name) {
        super(name);
    }
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(this.getName()+i);
        }
    }
}
public class test02 {
    public static void main(String[] args) {
        Thread.currentThread().setName("The main---");
        //通过构造器设置线程名称
        Demo02 tt=new Demo02("Demo02");

        tt.start();//线程的启动
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}

输出:

Demo021
The main---1
Demo022
The main---2
Demo023
Demo024
Demo025
The main---3
The main---4
The main---5

龟兔赛跑

兔子:Tuzi类

public class Tuzi extends Thread{
    public Tuzi(String name) {
        super(name);
    }

    @Override
    public void run() {
        while(true){
            System.out.println(Thread.currentThread().getName()+"===我是兔子我在跑!");
        }
    }
}

乌龟:Wugui类

public class Wugui extends Thread{
    public Wugui(String name) {
        super(name);
    }

    @Override
    public void run() {
        while(true){
            System.out.println(Thread.currentThread().getName()+"===我是乌龟我在跑!");
        }
    }
}

测试:guituTest类

public class guituTest {
    public static void main(String[] args) {
        Tuzi tz=new Tuzi("兔子");
        tz.start();

        Wugui wg=new Wugui("乌龟");
        wg.start();
    }
}

运行结果:一直在无序输出“兔子=我是兔子我在跑!
乌龟
=我是乌龟我在跑!”这两句话。

抢火车票

HuoChePiao类

public class HuoChePiao extends Thread{
    private static int ticketNum=10;

    public HuoChePiao(String name){
        super(name);
    }

    @Override
    //每个窗口就是一个线程
    public void run() {
            //每个窗口下有100人买票
            for (int i = 0; i <= 100; i++) {
                if (ticketNum > 0) {
                System.out.println("我在" + this.getName() + "买到了火车票,剩余的第" + ticketNum-- + "张车票");
            }
        }
    }
}

ChePiaoTest类

public class ChePiaoTest {
    public static void main(String[] args) {
        HuoChePiao hcp1=new HuoChePiao("窗口1");
        hcp1.start();
        HuoChePiao hcp2=new HuoChePiao("窗口2");
        hcp2.start();
        HuoChePiao hcp3=new HuoChePiao("窗口3");
        hcp3.start();
        HuoChePiao hcp4=new HuoChePiao("窗口4");
        hcp4.start();
    }
}

输出:

我在窗口1买到了火车票,剩余的第10张车票
我在窗口4买到了火车票,剩余的第7张车票
我在窗口4买到了火车票,剩余的第5张车票
我在窗口3买到了火车票,剩余的第8张车票
我在窗口2买到了火车票,剩余的第9张车票
我在窗口3买到了火车票,剩余的第3张车票
我在窗口4买到了火车票,剩余的第4张车票
我在窗口1买到了火车票,剩余的第6张车票
我在窗口3买到了火车票,剩余的第1张车票
我在窗口2买到了火车票,剩余的第2张车票

第二种方式:实现Runnable接口

public class Demo03 implements Runnable{

    @Override
    public void run() {
        for (int i = 1; i <=10; i++) {
            System.out.println(Thread.currentThread().getName()+"---"+i);
        }
    }
}
public class test03 {
    public static void main(String[] args) {
        //创建线程对象
        Demo03 tt=new Demo03();
        //启动线程
        //两个类之间若要产生关联,利用有参构造器。
        Thread t=new Thread(tt);
        t.start();
        for (int i = 1; i <=10 ; i++) {
            System.out.println(Thread.currentThread().getName()+"---"+i);
        }
    }
}

输出:

Thread-0---1
main---1
Thread-0---2
main---2
main---3
main---4
main---5
Thread-0---3
main---6
Thread-0---4
main---7
Thread-0---5
Thread-0---6
main---8
Thread-0---7
main---9
Thread-0---8
main---10
Thread-0---9
Thread-0---10

静态代理模式

创建接口BeiRenZhui

public interface BeiRenZhui {
    void maiHua();
    void kouHong();
}

新建类(被追的人JinHaiXin)

public class JinHaiXin implements BeiRenZhui{

    @Override
    public void maiHua() {
        System.out.println("买蓝色妖姬。。。花。。。");
    }

    @Override
    public void kouHong() {
        System.out.println("女王的权杖。。。口红。。。");
    }
}

新建类(被追的人XiaoPang)

public class XiaoPang implements BeiRenZhui{
    @Override
    public void maiHua() {
        System.out.println("买小雏菊。。。");
    }

    @Override
    public void kouHong() {
        System.out.println("买小羊皮。。。");
    }
}

新建代理人Shan

public class Shan implements BeiRenZhui{
    BeiRenZhui brz;
    public Shan(BeiRenZhui brz){
        this.brz=brz;
    }
    @Override
    public void maiHua() {
        brz.maiHua();
    }

    @Override
    public void kouHong() {
        brz.kouHong();
    }
}

新建追求者

public class ChiXinRen {
    public static void main(String[] args) {
        //先委托Shan追求JinHaiXin
        JinHaiXin jhx=new JinHaiXin();
        Shan s=new Shan(jhx);
        s.maiHua();
        s.kouHong();
        System.out.println("-------------");
        //未果,又委托Shan追求XiaoPang
        XiaoPang xp=new XiaoPang();
        Shan ss=new Shan(xp);
        ss.maiHua();
        ss.kouHong();
    }
}

运行结果:

买蓝色妖姬。。。花。。。
女王的权杖。。。口红。。。
-------------
买小雏菊。。。
买小羊皮。。。

第二种方式抢火车票

用此种方式比较好,原因:

1.共享资源。

2.实现接口,所以可以继承其他的类,但是第一种方式,java单继承,不能继承其他的类。

Ticket类

public class Ticket implements Runnable{
    private int ticketNum=10;
    @Override
    public void run() {
        for (int i = 1; i <=ticketNum ; i++) {
            if(ticketNum>0){
                System.out.println("我在"+Thread.currentThread().getName()+"买到了剩余的第"+ticketNum--+"张火车票!");
            }
        }
    }
}
public class ticketTest {
    public static void main(String[] args) {
        Ticket tk=new Ticket();
        Thread t1=new Thread(tk,"窗口1");
        t1.start();
        Thread t2=new Thread(tk,"窗口2");
        t2.start();
        Thread t3=new Thread(tk,"窗口3");
        t3.start();
    }
}

运行结果

我在窗口2买到了剩余的第10张火车票!
我在窗口1买到了剩余的第8张火车票!
我在窗口3买到了剩余的第9张火车票!
我在窗口3买到了剩余的第5张火车票!
我在窗口1买到了剩余的第6张火车票!
我在窗口2买到了剩余的第7张火车票!
我在窗口1买到了剩余的第3张火车票!
我在窗口3买到了剩余的第4张火车票!

第三种方式

之前的第一种、第二种方式:

public class Ticket implements Runnable{
     public void run(){
     
     }
}

run()方法不可以有返回值,并且不可以出现异常。

第三种方式是JDK1.5之后加入的。

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

//第三种方式:实现Callable接口,在实现的同时,加入泛型。这个泛型是call方法的返回值类型。
public class Demo04 implements Callable<Integer> {
    //重写call方法,这个方法:有返回值,有抛出异常
    @Override
    public Integer call() throws Exception {
        return new Random().nextInt(10);
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //缺点:创建线程方式比较繁琐
        //创建线程对象
        Demo04 t=new Demo04();
        //启动线程
        FutureTask<Integer> ft=new FutureTask<>(t);
        Thread tt=new Thread(ft);
        tt.start();

        //返回值自己获取
        System.out.println(ft.isDone());
        Integer i=ft.get();
        System.out.println(i);
        //获取返回值之后线程才结束
        System.out.println(ft.isDone());
    }
}

线程的生命周期

新生阶段

Thread tt=new Thread();

运行start()方法后进入就绪阶段

就绪阶段

有资格,无资源。万事俱备,只欠CPU调度。

CPU调度:run(),call()

运行阶段

有资格,有资源

运行阶段之后有两种可能:阻塞阶段或者消亡阶段。

遇到IO流等阻塞方法,进入阻塞阶段。

阻塞阶段

无资格,让资源。

解除阻塞后进入就绪阶段。

消亡阶段

  1. 正常执行,正常结束

  2. 出现异常

  3. 调用stop()方法

影响生命周期的方法

优先级别

public class guituTest {
    public static void main(String[] args) {
        Tuzi tz=new Tuzi("兔子");
        tz.setPriority(2);
        tz.start();

        Wugui wg=new Wugui("乌龟");
        wg.setPriority(8);
        wg.start();

    }
}

运行结果

兔子===我是兔子我在跑!
兔子===我是兔子我在跑!
兔子===我是兔子我在跑!
兔子===我是兔子我在跑!
兔子===我是兔子我在跑!
兔子===我是兔子我在跑!
兔子===我是兔子我在跑!
兔子===我是兔子我在跑!
乌龟===我是乌龟我在跑!
兔子===我是兔子我在跑!
兔子===我是兔子我在跑!
乌龟===我是乌龟我在跑!
乌龟===我是乌龟我在跑!
乌龟===我是乌龟我在跑!
乌龟===我是乌龟我在跑!
乌龟===我是乌龟我在跑!
乌龟===我是乌龟我在跑!
乌龟===我是乌龟我在跑!
乌龟===我是乌龟我在跑!
乌龟===我是乌龟我在跑!

说明:优先级别高,只能说明 优先 被CPU调用的概率高,而不是一定优先被调度。

posted @ 2020-09-03 22:41  XLR  阅读(167)  评论(0编辑  收藏  举报