其他分享
首页 > 其他分享> > 多线程之线程实现和状态

多线程之线程实现和状态

作者:互联网

多线程

1.多线程Thread概述

1.1线程简介

2. 线程实现

2.1 线程三种创建方式

2.2 线程实现->继承Thread类

2.21 继承Thread类创建线程代码演示

package threads.demo01;
//创建线程方式一:继承thread 类,重写run() 方法,调用start 开启线程
public class TestThread extends Thread{
    @Override
    public void run() {

        //run 方法线程体
        for (int i = 0; i < 10; i++) {
            System.out.println("我再测试run方法"+i);

        }

    }

    public static void main(String[] args) {
        //main 线程,主线程

        //创建一个线程对象
        TestThread testThread = new TestThread();
        //调用start()方法开启线程
        testThread.start();

        for (int i = 0; i < 10; i++) {
            System.out.println("我在学习多线程"+i);
        }

    }
}


运行结果

我在学习多线程0
我再测试run方法0
我在学习多线程1
我再测试run方法1
我在学习多线程2
我再测试run方法2
我在学习多线程3
我在学习多线程4
我在学习多线程5
我在学习多线程6
我再测试run方法3
我再测试run方法4
我再测试run方法5
我再测试run方法6
我再测试run方法7
我再测试run方法8
我再测试run方法9
我在学习多线程7
我在学习多线程8
我在学习多线程9


2.22 实现多线程同步下载图片代码演示


package threads.demo01;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
//练习thread ,实现多线程同步下载图片

public class TestThread1 extends Thread{
    private String url;//网络图片地址
    private String name;//保存的文件名

    public TestThread1(String url, String name) {
        this.url = url;
        this.name = name;
    }

    @Override
    //下载图片线程的执行体
    public void run() {//(2)使用多线程方法下载

        // 进入线程后,创建一个下载器,下载器通过 downloader 方法,传入 url 和 name 下载相应的资源
        WebDownloard webDownloard = new WebDownloard();
        webDownloard.dewnloard(url,name);
        System.out.println("下载的文件名:"+name);
    }

    public static void main(String[] args) {

        //(3)主方法内填入网址及名字,并运行
        TestThread1 testThread1 = new TestThread1("https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG","test1.jpg");
        TestThread1 testThread2 = new TestThread1("https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG","test2.jpg");
        TestThread1 testThread3 = new TestThread1("https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG","test3.jpg");

             testThread1.start();
             testThread2.start();
             testThread3.start();

    }


}

//下载器(1)
class WebDownloard{
    //下载方法
    public void dewnloard(String url,String name)  {


        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO 异常,图片copy失败");
        }
    }

}


运行结果

下载的文件名:test3.jpg
下载的文件名:test2.jpg
下载的文件名:test1.jpg


2.3 线程实现->实现Runnable接口


2.31 实现Runnable接口接口创建线程代码演示

package threads.demo01;
//实现Runnable:实现Runnable接口,重写run方法,执行线程需要丢入Runnable接口实现类,调用start方法
public class RunnableTest implements Runnable{
    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 10; i++) {
            System.out.println("线程的run方法");
        }

    }


    public static void main(String[] args) {
        //main线程,主线程

        for (int i = 0; i < 10; i++) {
            System.out.println("我在学习多线程");
        }

        //创建一个线程对象
        RunnableTest runnableTest = new RunnableTest();
        //创建线程对象,通过线程对象来开启我们的多线程,代理
        // Thread thread = new Thread(runnableTest);
        // thread.start();


        //简写
        //调用start()开启线程
        new Thread(runnableTest).start();
    }
}


运行结果

我在学习多线程
我在学习多线程
我在学习多线程
我在学习多线程
我在学习多线程
我在学习多线程
我在学习多线程
我在学习多线程
我在学习多线程
我在学习多线程
线程的run方法
线程的run方法
线程的run方法
线程的run方法
线程的run方法
线程的run方法
线程的run方法
线程的run方法
线程的run方法
线程的run方法



2.32 实现Runnable接口copy图片代码演示


package threads.demo01;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
//使用实现Runnable接口,重写run方法,copy图片
public class RunnableCopyTest implements Runnable{

    private String url;
    private String name;

    public RunnableCopyTest(String url, String name) {
        this.url = url;
        this.name = name;
    }

    @Override
    public void run() {
        DownloaderUrl downloaderUrl = new DownloaderUrl();
        downloaderUrl.download(url,name);
        System.out.println("文件名称为:"+name);

    }


    public static void main(String[] args) {
        RunnableCopyTest t1 = new RunnableCopyTest("https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG", "amage1.jpg");
        RunnableCopyTest t2 = new RunnableCopyTest("https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG", "amage2.jpg");
        RunnableCopyTest t3 = new RunnableCopyTest("https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG", "amage3.jpg");

        new Thread(t1).start();
        new Thread(t2).start();
        new Thread(t3).start();

    }

}

class DownloaderUrl{

    public void download(String url,String name){

        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常,文件复制失败");
        }
    }
}


运行结果

文件名称为:amage3.jpg
文件名称为:amage2.jpg
文件名称为:amage1.jpg



2.33 并发问题买火车票案例代码演示


package threads.demo01;
//多线程同时操作同一个对象
//买火车票的例子

// 问题:产生了并发问题,多个线程同时对一个资源进行操作,线程不安全,发生了数据紊乱
public class TicketRunnableTest implements Runnable{

    // 票数
    private int ticketNumb=20;

    @Override
    public void run() {

        while (true){
            if(ticketNumb<=0){
                break;
            }
            // 模拟演示
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"抢到了第"+ticketNumb--+"张火车票");
        }

    }

    public static void main(String[] args) {
        TicketRunnableTest t1 = new TicketRunnableTest();
        new Thread(t1,"张三").start();
        new Thread(t1,"李四").start();
        new Thread(t1,"黄牛党").start();

    }

}


运行结果

黄牛党抢到了第20张火车票
张三抢到了第19张火车票
李四抢到了第18张火车票
黄牛党抢到了第17张火车票
张三抢到了第16张火车票
李四抢到了第15张火车票
黄牛党抢到了第14张火车票
张三抢到了第13张火车票
李四抢到了第12张火车票
黄牛党抢到了第11张火车票
张三抢到了第10张火车票
李四抢到了第9张火车票
黄牛党抢到了第8张火车票
张三抢到了第7张火车票
李四抢到了第6张火车票
黄牛党抢到了第5张火车票
张三抢到了第4张火车票
李四抢到了第3张火车票
黄牛党抢到了第2张火车票
张三抢到了第1张火车票
李四抢到了第0张火车票
黄牛党抢到了第-1张火车票


2.34 模拟龟兔赛跑案例代码演示


/*
1.首先来个赛道距离,然后要离终点越来越近
2.判断比赛是否结束
3.打印出胜利者
4.龟兔赛跑开始
5.故事中是乌龟赢的,兔子需要睡觉,所以我们来模拟兔子睡觉。
6.终于,乌龟赢得比赛。
*/

/*
1.定义一个赢家
2.设定赛道
3.判断输赢
4.确定比赛是否结束

 */
package threads.demo01;
// 模拟龟兔赛跑
public class RaceTest implements Runnable{

    // 胜利者
    private static String winner;// static 保证在调用时只有一个 winner

    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {//赛道

             // 模拟兔子休息
            if(Thread.currentThread().getName().equals("兔子")&&i%10==0){

                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }


            // 判断比赛是否结束
            Boolean flag = gameOver(i);
            // 如果比赛结束 停止程序
            if (flag){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");

        }

    }
    //判断输赢
    //假如winner不为空就说明已经有冠军
    //假如steps>=100,则产生冠军
    //否则比赛还没结束

    //判断是否完成比赛
    public Boolean  gameOver(int step){
        // 判断是否有胜利者
        if (winner!=null){// 已经存在胜利者
            return true;
        }
        {//这里{}只是一个代码块,可以不写,直接if语句,方便理解。写了美观
            if (step >= 100) {
                winner = Thread.currentThread().getName();
                System.out.println("胜利者是:" + winner);
                return true;
            }
        }
        return false;

    }


    public static void main(String[] args) {

        RaceTest raceTest = new RaceTest();
        new Thread(raceTest,"兔子").start();
        new Thread(raceTest,"乌龟").start();
    }


}



运行结果

乌龟跑了0步
乌龟跑了1步
乌龟跑了2步
乌龟跑了3步
乌龟跑了4步
乌龟跑了5步
乌龟跑了6步
乌龟跑了7步
乌龟跑了8步
乌龟跑了9步
乌龟跑了10步
乌龟跑了11步
乌龟跑了12步
乌龟跑了13步
乌龟跑了14步
乌龟跑了15步
乌龟跑了16步
乌龟跑了17步
乌龟跑了18步
乌龟跑了19步
乌龟跑了20步
乌龟跑了21步
乌龟跑了22步
乌龟跑了23步
乌龟跑了24步
乌龟跑了25步
乌龟跑了26步
乌龟跑了27步
乌龟跑了28步
乌龟跑了29步
乌龟跑了30步
乌龟跑了31步
乌龟跑了32步
乌龟跑了33步
乌龟跑了34步
乌龟跑了35步
乌龟跑了36步
乌龟跑了37步
乌龟跑了38步
乌龟跑了39步
乌龟跑了40步
乌龟跑了41步
乌龟跑了42步
乌龟跑了43步
乌龟跑了44步
兔子跑了0步
乌龟跑了45步
兔子跑了1步
乌龟跑了46步
兔子跑了2步
兔子跑了3步
乌龟跑了47步
兔子跑了4步
乌龟跑了48步
兔子跑了5步
乌龟跑了49步
兔子跑了6步
乌龟跑了50步
兔子跑了7步
兔子跑了8步
乌龟跑了51步
兔子跑了9步
乌龟跑了52步
乌龟跑了53步
乌龟跑了54步
乌龟跑了55步
乌龟跑了56步
乌龟跑了57步
乌龟跑了58步
乌龟跑了59步
乌龟跑了60步
乌龟跑了61步
乌龟跑了62步
乌龟跑了63步
乌龟跑了64步
乌龟跑了65步
乌龟跑了66步
乌龟跑了67步
乌龟跑了68步
乌龟跑了69步
乌龟跑了70步
乌龟跑了71步
乌龟跑了72步
乌龟跑了73步
乌龟跑了74步
乌龟跑了75步
乌龟跑了76步
乌龟跑了77步
乌龟跑了78步
乌龟跑了79步
乌龟跑了80步
乌龟跑了81步
乌龟跑了82步
乌龟跑了83步
乌龟跑了84步
乌龟跑了85步
乌龟跑了86步
乌龟跑了87步
乌龟跑了88步
乌龟跑了89步
兔子跑了10步
乌龟跑了90步
兔子跑了11步
乌龟跑了91步
乌龟跑了92步
乌龟跑了93步
乌龟跑了94步
乌龟跑了95步
乌龟跑了96步
乌龟跑了97步
兔子跑了12步
乌龟跑了98步
兔子跑了13步
乌龟跑了99步
兔子跑了14步
胜利者是:乌龟



2.4 线程实现->实现Callable接口(了解即可)

2.41 利用callable 改造下载图片案例代码演示

package threads.demo01;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
//线程创建方式三:实现calladle接口
//重写实现的是call方法,并需要设置返回Boolean值(也可以设置其他类型返回值)
/*
callable的好处
  1.可以定义返回值
  2.可以抛出异常
*/
/*
    1. 实现Callable接口
    2.实现call方法
    3.创建执行服务
    4.提交执行
    5.获取结果
    6.关闭服

 */
//利用callable 改造下载图片案例
public class TestCallable implements Callable<Boolean> {

    private  String url;//网络图片地址
    private  String name;//保存的文件名

    public TestCallable(String name,String url) {
        this.name = name;
        this.url=url;
    }

    //下载图片线程的执行体
    @Override
    public Boolean call() {
        WebDownLoader1 webDownLoader1 = new WebDownLoader1();
        webDownLoader1.DownLoader(url,name);
        System.out.println("下载了文件为:"+name);
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable t1 = new TestCallable("1.jpg","https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG");
        TestCallable t2 = new TestCallable("2.jpg","https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG");
        TestCallable t3 = new TestCallable("3.jpg","https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG");

        //4.创建执行服务
        ExecutorService ser= Executors.newFixedThreadPool(3);

        //5.提交执行
        Future<Boolean> result1=ser.submit(t1);
        Future<Boolean> result2=ser.submit(t2);
        Future<Boolean> result3=ser.submit(t3);

        //6.获取结果
        Boolean r1 =result1.get();
        Boolean r2 =result1.get();
        Boolean r3 =result1.get();
        System.out.println(r1);
        System.out.println(r2);
        System.out.println(r3);

        //7.关闭服务:
        ser.shutdownNow();
    }

}
class WebDownLoader1 {
    //下载方法
    public void DownLoader(String url,String name) {
        try {
            FileUtils.copyURLToFile(new URL(url), new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常 download方法出现问题");
        }
    }
}


运行结果

下载了文件为:2.jpg
下载了文件为:3.jpg
下载了文件为:1.jpg
true
true
true

2.5 静态代理


2.51 实现静态代理对比Thread代码演示

package threads.demo01;
//静态代理模式总结
//真实对象和代理对象都要实现同一个接口
//代理对象要代理真实角色,做了“结婚前”和“结婚后”的事,而真实对象只需要“结婚”

/*
    好处:
        1. 代理对象可以做很多真实对象做不了的事情
        2. 真实对象专注做自己的事情
 */

//  Runnable   对比
       /*
                  //创建一个线程对象
               RunnableTest runnableTest = new RunnableTest();
                //创建线程对象,通过线程对象来开启我们的多线程,代理
                // Thread thread = new Thread(runnableTest);
                // thread.start();

                //简写  调用start()开启线程
                new Thread(runnableTest).start();

               Runnable接口只有抽象run()方法:public abstract void run();
               Thread相对于婚庆公司,也实现了Runnable接口:  class Thread implements Runnable
               并且Thread构造方法需要传入实现Runnable接口的对象:public Thread(Runnable target)
               Thread的括号里是真正的线程对象


                    new  Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("我爱你");
                    }
                    }).start();

         Lambda表达式:  new  Thread(()->System.out.println("我爱你")).start();



*/
//  实现静态代理对比Thread演示

public class StaticProxy {
    public static void main(String[] args) {

        you you = new you();//你要结婚
        you.HappyMarry();
        System.out.println("使用静态代理==========");
        weddingCompany weddingCompany = new weddingCompany(new you());//真实要结婚的目标
        weddingCompany.HappyMarry();

        /*
        多线程原理与静态代理模式很像
        Thread和WeddingCompany都是代理,都代理了真实对象
         */
    }

}

interface Marry{
    void HappyMarry();
}
// 实际需要结婚的角色 You
class you implements Marry{

    @Override
    public void HappyMarry() {
        System.out.println("我要结婚了,超开心");
    }
}
//代理角色,帮助你结婚
class weddingCompany implements Marry{

    private Marry tager;//创建目标对象

    public weddingCompany(Marry tager) {
        this.tager=tager;
    }


    @Override
    public void HappyMarry() {
        befor();
        this.tager.HappyMarry(); //目标对象进行结婚
        after();
    }


    private void befor() {
        System.out.println("结婚之前,布置现场");
    }
    private void after() {
        System.out.println("结婚之后,收尾款");
    }
}

运行结果

我要结婚了,超开心
使用静态代理==========
结婚之前,布置现场
我要结婚了,超开心
结婚之后,收尾款


2.6 Lamda表达式


public interface Runnable{
       public abstract void run();
}

2.61 推导lamda表达式代码演示

package threads.demo01;
/**
 * 推导lamda表达式
 */
public class TestLambda {
    public static void main(String[] args) {

        Like like = new Like();
        like.lambda();

        Like1 like1 = new Like1();
        like1.lambda();


        // //4.局部内部类
        class Like2 implements ILike{

            @Override
            public void lambda() {
                System.out.println("我是局部内部类");
            }
        }
        Like2 like2 = new Like2();
        like2.lambda();


        // //5.匿名内部类,没有类的名称,必须借助接口或者父类
        ILike like3 = new ILike() {
            @Override
            public void lambda() {
                System.out.println("我是匿名内部类");
            }
        };


        /*
        //6.lamda简化
        like3 = ()-> {
            System.out.println("I like lambda5");
        };
        like3.lambda();
*/

    }

    //3. 静态内部类
    static class Like1 implements ILike{

        @Override
        public void lambda() {
            System.out.println("我是静态内部类");
        }
    }



}

// 1.定义一个函数式接口
interface ILike{
    void lambda();
};

// 2.实现类
class Like implements ILike{
    @Override
    public void lambda() {
        System.out.println("我是外部类");
    }
}

运行结果

我是外部类
我是静态内部类
我是局部内部类
我是匿名内部类


2.62 lamda表达式简化代码演示

public class Demo14_LamdaCase2 {
    public static void main(String[] args) {
        // 1.lamda
        ILove love = (int a) -> {
            System.out.println("I love you -->" + a);
        };
        // 2.lamda简化1.0
        love = (a) -> {
            System.out.println("I love you -->" + a);
        };
        // 3.lamda简化2.0
        love = a -> {
            System.out.println("I love you -->" + a);
        };
        // 3.lamda简化3.0
        love = a -> System.out.println("I love you -->" + a);

        /**总结:
         * Lambda表达式只能有一行代码(函数式接口)的情况下才能简化成为一条,如果有多行,那么就用代码块包裹{}
         * 前提是接口为函数式接口(只能有一个方法)
         * 多个参数也可以去掉参数类型,要去掉就都去掉,必须加上()
         */

        love.love(520);
    }
}

interface ILove {
    void love(int a);
}



3.线程状态

3.1 线程五大状态:


jj

kk

3.2 线程方法


3.21 线程停止

3.21 使用标志位线程停止代码演示:

package threads.demo02;
/*
    测试stop
    1. 建议线程正常停止-->利用次数,不建议死循环(死循环也要限制运行速度,防止cpu卡死)
    2.建议使用标志位-->设置一个标志位
    3.不要使用 stop 或者 destroy 等过时或者JDk不建议使用的方法
 */
//测试stop
public class TestStop implements Runnable{

    //1.设置一个标志位
    private boolean flag=true;
    //多线程方法
    @Override
    public void run() {
        int i=0;
        while (flag) {
                System.out.println("run...Thread" + i++);
        }

    }


    //2.设置一个公开的方法停止线程,转换标志位
    public void stop(){
        this.flag=false;
    }

    public static void main(String[] args) {
        //开启多线程
        TestStop testStop = new TestStop();
        new Thread(testStop).start();

        for (int i = 0; i < 30; i++) {
            System.out.println("主线程在运行"+i);

            if(i==20){
                //3.调用stop方法切换标志位,让线程停止
                testStop.stop();
                System.out.println("线程停止了");
            }

        }
    }
}

运行结果

主线程在运行0
run...Thread0
主线程在运行1
run...Thread1
主线程在运行2
主线程在运行3
主线程在运行4
主线程在运行5
主线程在运行6
主线程在运行7
主线程在运行8
主线程在运行9
主线程在运行10
主线程在运行11
主线程在运行12
主线程在运行13
主线程在运行14
主线程在运行15
主线程在运行16
主线程在运行17
主线程在运行18
run...Thread2
run...Thread3
run...Thread4
run...Thread5
run...Thread6
run...Thread7
run...Thread8
run...Thread9
run...Thread10
run...Thread11
run...Thread12
run...Thread13
run...Thread14
run...Thread15
run...Thread16
run...Thread17
run...Thread18
run...Thread19
run...Thread20
run...Thread21
run...Thread22
run...Thread23
run...Thread24
run...Thread25
run...Thread26
run...Thread27
run...Thread28
主线程在运行19
主线程在运行20
run...Thread29
线程停止了
主线程在运行21
主线程在运行22
主线程在运行23
主线程在运行24
主线程在运行25
主线程在运行26
主线程在运行27
主线程在运行28
主线程在运行29



3.22 线程休眠

3.22 模拟网络延迟代码演示:

package threads.demo02;

import threads.demo01.TicketRunnableTest;
//模拟网络延迟,放大问题的发生性
public class TestSleep1 implements Runnable{

    // 票数
    private int ticketNumb=10;

    @Override
    public void run() {

        while (true){
            if(ticketNumb<=0){
                break;
            }
            // 模拟演示
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"抢到了第"+ticketNumb--+"张火车票");
        }

    }

    public static void main(String[] args) {

        TestSleep1 t1 = new TestSleep1();
        new Thread(t1,"张三").start();
        new Thread(t1,"李四").start();
        new Thread(t1,"黄牛党").start();

    }
}


运行结果

黄牛党抢到了第10张火车票
张三抢到了第9张火车票
李四抢到了第8张火车票
李四抢到了第6张火车票
张三抢到了第5张火车票
黄牛党抢到了第7张火车票
黄牛党抢到了第4张火车票
张三抢到了第3张火车票
李四抢到了第2张火车票
李四抢到了第1张火车票
张三抢到了第0张火车票
黄牛党抢到了第-1张火车票

3.22 模拟倒计时代码演示:

package threads.demo02;

import java.text.SimpleDateFormat;
import java.util.Date;

//模拟倒计时
public class TestSleep2 {

    public static void main(String[] args) {

        try {
            TestSleep2.tenDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        //打印当前系统时间
        Date date = new Date(System.currentTimeMillis()); //获取系统当前时间

        while (true){
            try {
                Thread.sleep(1000);
                System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));//打印时间格式
                date = new Date(System.currentTimeMillis()); //更新系统当前时间

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


    }

    //模拟倒计时
    public static void tenDown() throws InterruptedException {

        int numb=10;
        while (true){
            Thread.sleep(1000);
            System.out.println(numb--);

            if(numb<=0) {
                break;
            }
        }

    }

}



运行结果

10
9
8
7
6
5
4
3
2
1
16:54:26
16:54:27

3.23 线程礼让_yield

3.23 测试礼让线程代码演示:

package threads.demo02;

/**
 * 测试礼让线程
 * 礼让不一定成功,看cpu心情
 */
//测试礼让线程

public class TestYeild {

    public static void main(String[] args) {
        MyYeild testYeild = new MyYeild();
        new Thread(testYeild, "a").start();
        new Thread(testYeild, "b").start();
    }



}
class MyYeild implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "开始运行");

        Thread.yield();//礼让
        System.out.println(Thread.currentThread().getName() + "运行停止");
    }
}

运行结果

a开始运行
b开始运行
b运行停止
a运行停止

3.25 线程强制执行_join

3.25 测试join代码演示:

package threads.demo02;
/**
 * 测试join
 * 插队
 */
public class TestJoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("VIP来插队了"+i);
        }
    }


    public static void main(String[] args) throws InterruptedException {
        //启动我们的线程
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);

        //主线程
        for (int i = 0; i < 10; i++) {

            if(i==5){
                thread.start();
                thread.join();//插队
            }
            System.out.println("main线程"+i);
        }

    }

}

运行结果

main线程0
main线程1
main线程2
main线程3
main线程4
VIP来插队了0
VIP来插队了1
VIP来插队了2
VIP来插队了3
VIP来插队了4
VIP来插队了5
VIP来插队了6
VIP来插队了7
VIP来插队了8
VIP来插队了9
VIP来插队了10
VIP来插队了11
VIP来插队了12
VIP来插队了13
VIP来插队了14
VIP来插队了15
VIP来插队了16
VIP来插队了17
VIP来插队了18
VIP来插队了19
main线程5
main线程6
main线程7
main线程8
main线程9


3.26 线程状态观测

3.26 观察测试线程状态代码演示:

package threads.demo02;
//观察测试线程的状态
public class TestState {

    public static void main(String[] args) throws InterruptedException {

        final Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                System.out.println("//////////////");
                
            }
        });

        //观察状态
        Thread.State state = thread.getState();
        System.out.println(state);


        //观察启动后
        thread.start();//启动线程
        state=thread.getState();
        System.out.println(state);//Run

        while (state!=Thread.State.TERMINATED){//只要现成不终止,就一直输出状态
            Thread.sleep(100);
            state=thread.getState();//更新线程状态
            System.out.println(state);//输出状态

        }

        //死亡后的线程不能再启动了,启动会报异常
        //thread.start();
    }
    
}

运行结果

NEW
RUNNABLE
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
RUNNABLE
RUNNABLE
//////////////
TERMINATED


3.27 线程优先级【Priority】

3.27 测试线程优先级代码演示:

package threads.demo02;
//测试线程的优先级
//priority  优先事项;最重要的事;首要事情;优先;优先权;重点;
public class TestPriority {
    public static void main(String[] args) {
        //主线程默认优先级
        System.out.println(Thread.currentThread().getName()+"===>"+Thread.currentThread().getPriority());

        //设置线程中优先级别
        MyPriority myPriority = new MyPriority();
        Thread t1 = new Thread(myPriority);
        Thread t2 = new Thread(myPriority);
        Thread t3 = new Thread(myPriority);
        Thread t4 = new Thread(myPriority);
        Thread t5 = new Thread(myPriority);

        t1.start(); //子程序默认优先级

        //先设置优先级,再设置启动
        t2.setPriority(6);
        t2.start();

        t3.setPriority(7);
        t3.start();

        t4.setPriority(Thread.MAX_PRIORITY);//MAX_PRIORITY最高级10
        t4.start();

        t5.setPriority(3);
        t5.start();

        /*t5.setPriority(-1);//低于边界1 抛出异常
        t5.start();

        t6.setPriority(11);//高于边界10 抛出异常
        t6.start();*/


    }
}


class MyPriority implements Runnable{

    //子线程优先级打印
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"===>"+Thread.currentThread().getPriority());
    }
}

运行结果

main===>5
Thread-0===>5
Thread-2===>7
Thread-3===>10
Thread-1===>6
Thread-4===>3


3.28 守护线程【Daemon】

3.28 测试守护线程代码演示:

package threads.demo02;
//测试守护线程
//你要保护你爱的人
public class TestDaemon {
    public static void main(String[] args) {

        You you = new You();
        Lover lover = new Lover();

        Thread thread = new Thread(you);
        thread.setDaemon(true);//默认是false表示是用户线程,正常的线程都是用户线程

        thread.start();//你   守护线程启动
        new Thread(lover).start();//爱人    用户线程启用


    }
}

//你
class You implements Runnable{

    @Override
    public void run() {

        while (true){
            System.out.println("你守护着你爱的人");
        }

    }
}
//爱的人
class Lover implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("人生一百年");
        }
        System.out.println("======goodbye======");
    }
}


更多参考

狂神说java-多线程详解

标签:状态,run,Thread,线程,new,乌龟,多线程,public
来源: https://www.cnblogs.com/xingchenyang/p/16512623.html