多线程

多线程

线程:Thread

​ 单线程:单个任务,一个执行路径,一个顺序流。

​ 多线程:多个任务执行,多个路径执行,多个顺序流

​ 三高网站:高性能、高可用、高并发。

​ 多线程的优点:效率高。

​ 串行:在同一时间内,多个任务快速串行——》多线程

​ 并行:在同一个时间段内多个任务同时执行。

创建线程的三种方式

继承Thread,重写run()方法

public class ThreadDemo01 extends Thread{
    public static void main(String[] args) throws InterruptedException {
        ThreadDemo01 threadDemo01=new ThreadDemo01();
        threadDemo01.start();
        for(int i=0;i<=10;i++){
            System.out.println("跑步");
            Thread.sleep(50);
        }
    }
    @Override
    public void run() {
        for (int i=0;i<=20;i++){
            System.out.println( "吃饭");
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

实现Runnable,重写run()方法,方法内部定义线程体

class ThreadDemo02 implements  Runnable{
    public static void main(String[] args) throws InterruptedException {
        ThreadDemo02 threadDemo02=new ThreadDemo02();
        new Thread(threadDemo02).start();
        for(int i=0;i<=10;i++){
            System.out.println("做梦");
            Thread.sleep(50);
        }

    }


    @Override
    public void run() {
        for (int i=0;i<=20;i++){
            System.out.println( "睡觉");
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

通过Callable接口call() 定义线程体

public class ThreadDemo05 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Match2 match = new Match2();

        //通过线程池 固定大小线程池2个  static ExecutorService newFixedThreadPool(int nThreads)
        //1.创建执行服务
        ExecutorService server = Executors.newFixedThreadPool(2);
        //2.提交任务  <T> Future<T> submit(Callable<T> task) 提交值返回任务以执行并返回表示任务的挂起结果的Future。
        Future<Integer> f1 = server.submit(match);
        Future<Integer> f2 = server.submit(match);

        //3.获取结果
        Integer result1 = f1.get();
        Integer result2 = f2.get();
        System.out.println(result1);
        System.out.println(result2);

        //4.结束服务
        server.shutdown();

    }
}

//比赛
class Match2 implements Callable<Integer> {
    //结束标识
    private String winner;  //记录赢的人的名字


    /*
        可以抛出异常
     */
    @Override
    public Integer call() throws InterruptedException {
        //i作为步数
        for(int i=1;i<=100;i++){
            //是否为兔子
            System.out.println(Thread.currentThread().getName()+"正在跑第"+i+"步");
            if("兔子".equals(Thread.currentThread().getName()) && i%20==0){
               Thread.sleep(20);
            }
            //结束判断
            if(checkOver(i)){
                return i;
            }
        }
        return null;
    }

    //结束的条件判定  返回值: true结束   false不结束
    public boolean  checkOver(int steps){
        boolean flag = false;
        //有人赢了
        if(winner != null){
            return true;
        }
        //自己赢了
        if(steps==100){
            winner = Thread.currentThread().getName();
            return true;
        }
        return false;
    }
}

练习题

龟兔赛跑:

乌龟一直不停的再跑

兔子每次跑20步休息两秒

class ThreadDemo04 implements Runnable {

    int i=0;
    String string;
    @Override
    public void run() {
        while (true){
            i++;
            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
            if ("兔子".equals(Thread.currentThread().getName())&&i%20==0){
                try {
                    Thread.sleep(15);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if(flg(i)){
                break;
            }
        }
    }
    public boolean flg(int k){
        boolean flge=false;
        if (string!=null){
            return true;
        }
        if (k==100){
            string=Thread.currentThread().getName();
            return true;
        }
        return false;
    }
    public static void main(String[] args) {
        ThreadDemo04 threadDemo04=new ThreadDemo04();
        Thread thread01=new Thread(threadDemo04,"乌龟");
        Thread thread02=new Thread(threadDemo04,"兔子");
        thread01.start();
        thread02.start();
    }
}

Sleep线程睡眠****

public class SleepText {
    public static void main(String[] args) {
        Thread thread=new Thread(){
            @Override
            public void run() {
                int i=10;
                while (i>=0){
                    try {
                        sleep(1000);
                        System.out.println("时间结束还有"+i--+"秒");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("时间到");
            }
        };
        thread.start();
    }
}

yield

​ 礼让线程 给了其他线程更多的执行机会,但是不能决定是否其他线程一定执行,要看cpu的调度


public class YieldDemo02 implements Runnable{
    public static void main(String[] args) {
        YieldDemo02  yd = new YieldDemo02();
        new Thread(yd,"年轻人").start();
        new Thread(yd,"老大爷").start();
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"开始执行");
         System.out.println(Thread.currentThread().getName()+"礼让");
        Thread.yield(); //礼让
        System.out.println(Thread.currentThread().getName()+"收礼");
    }
}

Join:加入线程(插队线程)

Join()等待插队线程执行完毕,当前线程才能继续执行

Join(ms)最多只等待xxm的时间。

class Join1 implements Runnable{
    private Object Join2;

    @Override
    public void run() {
        System.out.println("想抽烟");
        System.out.println("喊儿子去买");
        System.out.println("给钱");
        Thread thread=new Thread(new Join2());
        thread.start();
        try {
            
            
            thread.join();
            
            
            
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("接过煊赫门");
        System.out.println("开始抽");
    }
}
class Join2 implements Runnable{
    @Override
    public void run() {
        int i=10;
        System.out.println("儿子拿钱");
        while (i>=0) {
            try {
                Thread.sleep(1000);
                System.out.println("来回花了" + i-- + "秒");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("买煊赫门");
        System.out.println("给父亲");
    }
}
class Join3 {
    public static void main(String[] args) {
       Thread thread= new Thread(new Join1());
       thread.start();
    }
}

获取当前线程的状态:观察线程的运行周期

Thread类中提供一个属性:getState()获取一个线程当前的一个状态

返回一个Thread.State枚举类型

class State{

    public static void main(String[] args) {

        Thread thread=new Thread(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"-->"+getState());
                for (int i=0;i<10;i++){
                    try {
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName()+"-->"+getState());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
                System.out.println(Thread.currentThread().getName()+"-->"+getState());
            }
        };
        System.out.println(Thread.currentThread().getName()+"-->"+thread.getState());
        thread.start();
        System.out.println(Thread.currentThread().getName()+"-->"+thread.getState());

        while(true){
            System.out.println(thread.getState());
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //当th1执行完毕进入终止状态结束打印
            if(thread.getState().equals(Thread.State.TERMINATED)){
                System.out.println(thread.getState());
                break;
            }
        }
    }
}

线程优先级:

每一个线程都存在优先级:优先级执行的可能性

优先级只能放大执行的机会,不代表一定先执行或者后执行

class YouXianJ{
    public static void main(String[] args) {
        Thread thread=new Thread(){
            @Override
            public void run() {
                System.out.println(1);
            }
        };
        Thread thread2=new Thread(){
            @Override
            public void run() {
                System.out.println(5);
            }
        };
        Thread thread3=new Thread(){
            @Override
            public void run() {
                System.out.println(10);
            }
        };
        //设置优先级
        thread.setPriority(1);
        thread2.setPriority(5);
        thread3.setPriority(10);
        thread.start();
        thread2.start();
        thread3.start();

    }
}

中断线程

void interrupt() 为一个线程添加一个中断标识。

​ static boolean interrupted() interrupted方法判断当前线程已经被添加过中断标识(是否当前线程调用过 interrupt()方法).同时复位中断标识。
​ boolean isInterrupted() 判断线程是否添加过中断标识,但是不会清楚这个标识。

以上三个方法都不能实现线程的终止,只是添加|判断标识,配合break,return…一起使用。

如果一个线程执行完毕,会自动复位|清除终止标识

public class InterruptDemo07 {
    public static void main(String[] args) {
        Thread th = new Thread(()->{
            int i = 1;
            while(true){
                System.out.println("我是th线程"+i++);
                if(Thread.interrupted()==true){
                    System.out.println("结束");
                    System.out.println("结束之前最后判断状态"+Thread.currentThread().isInterrupted());
                    break;
                }
            }
        });
        th.start();

        System.out.println(th.isInterrupted());
        
        th.interrupt();

       for(int i=1;i<=10;i++){
           System.out.println(th.isInterrupted());
           try {
               Thread.sleep(10);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }


    }
}

守护线程

守护线程与用户线程区别:
守护线程,就是用来守护用户线程的,当用户线程执行完毕,守护线程会直接结束。
创建的线程默认用户线程。
垃圾回收器就是一个典型的守护线程。
如何设置一个线程为守护线程: void setDaemon(boolean on) 将此线程标记为 daemon线程或用户线程。 true->守护线程 false->用户线程。
先设置守护线程,然后再start()。


public class OtherDemo06 {
    public static void main(String[] args) {
        Thread th = new Thread(()->{
            int i = 1;
            while(true){
                System.out.println("我是守护线程"+i++);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        //设置守护线程
        th.setDaemon(true);

        //开启线程
        th.start();

        //主线程默认用户线程
        for(int i=1;i<=20;i++){
            System.out.println("main用户线程"+i);
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

线程安全

同步方法

public class SynchonzedTexte implements Runnable {
    int tickets=100;
    @Override
    //同步方法syncharonized修饰
    public synchronized void run() {

        while (true) {
            //A B C
            if (tickets <= 0) {
                break;
            }
            //A B C
            System.out.println(Thread.currentThread().getName() + "正在购买第" + tickets-- + "张票");

            //模拟网络延迟
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        SynchonzedTexte synchonzedTexte = new SynchonzedTexte();
        //创建3个线程
        new Thread(synchonzedTexte,"zhangsan").start();
        new Thread(synchonzedTexte,"lisi").start();
        new Thread(synchonzedTexte,"wangwu").start();
    }
}

同步块:类.class

//synchronized(类.class){}
class SynchonzedTexte01 implements Runnable {
    int tickets = 100;
    @Override
    public void run() {
        while (true) {
            synchronized (SynchonzedTexte01.class) {
                if (tickets <= 0) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "正在购买第" + tickets-- + "张票");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        SynchonzedTexte01 synchonzedTexte01 = new SynchonzedTexte01();

        new Thread(synchonzedTexte01,"zhangsan").start();
        new Thread(synchonzedTexte01,"lisi").start();
        new Thread(synchonzedTexte01,"wangwu").start();
    }
}

同步块:this

//synchronized(this){}
class SynchonzedTexte02 implements Runnable {
    int tickets = 100;

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

    public static void main(String[] args) {
        SynchonzedTexte02 synchonzedTexte02 = new SynchonzedTexte02();
        //创建3个线程
        new Thread(synchonzedTexte02,"zhangsan").start();
        new Thread(synchonzedTexte02,"lisi").start();
        new Thread(synchonzedTexte02,"wangwu").start();
    }
}

同步块:资源

synchronized(资源){}
class SynchonzedTexte03 implements Runnable {
    Integ integ=new Integ();
    @Override
    public void run() {
        while (true) {
            synchronized (integ) {
                if (integ.integer <= 0) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "正在购买第" + integ.integer-- + "张票");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        SynchonzedTexte03 synchonzedTexte03 = new SynchonzedTexte03 ();
        //创建3个线程
        new Thread(synchonzedTexte03,"zhangsan").start();
        new Thread(synchonzedTexte03,"lisi").start();
        new Thread(synchonzedTexte03,"wangwu").start();
    }
}

class Integ{
    Integer integer=50;
}

生产者消费者问题:红绿灯

public class ShengchanZhe {
    public static void main(String[] args) {
        Seet seet=new Seet();
        new Thread(new Car1(seet)).start();
        new Thread(new Man1(seet)).start();
    }
}

class Car1 implements Runnable{
    Seet seet;
    public Car1(Seet seet) {
        this.seet = seet;
    }

    @Override
    public void run() {
        while (true){
            seet.caR();
        }
    }
}
class Man1 implements Runnable{
    Seet seet;
    public Man1(Seet seet) {
        this.seet = seet;
    }

    @Override
    public void run() {
        while (true){
            seet.maN();
        }
    }
}


class Seet{
    boolean aBoolean=false;
    public synchronized void caR() {
        if (aBoolean==false){

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("车走");
            aBoolean=true;
            this.notify();
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public synchronized void maN() {
        if (aBoolean==true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("人走");
            aBoolean=false;
            this.notify();
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值