一.线程的三种创建方式

1.继承Thread类

package demo01;//创建线程方式一,继承thread类 ,重写run()方法,调用start开启线程

//总结:线程开始,不一定立即执行,由cpu调度执行

public class TestThread extends Thread{

    @Override
    public void run(){
        //run方法线程体
        for(int i=0;i<20;i++){
            System.out.println("我在看代码"+i);
        }
    }

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

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

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

2.实现Runable接口
优点:避免单继承的局限性,灵活方便,方便同一个对象被多个线程所使用

package demo01;

//创建线程方式2,实现Runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
public class TestThread3 implements Runnable{
    @Override
    public void run(){
        //run方法线程体
        for(int i=0;i<20;i++){
            System.out.println("我在看代码"+i);
        }
    }

    public static void main(String[] args){
        //创建runnable接口的实现类对象
        TestThread3 testThread3 = new TestThread3();

        //创建线程对象,通过线程对象来开启线程,代理
        //Thread hread = new Thread(testThread3);
        //thread.start();
        new Thread(testThread3).start();

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

3.实现callable接口

public class TestCallable implements Callable<Boolean> {

    private String url;
    private String name;

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

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

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable t1 = new TestCallable("https://profile.csdnimg.cn/0/8/D/1_weixin_43822647","1.jpg");
        TestCallable t2 = new TestCallable("https://profile.csdnimg.cn/0/8/D/1_weixin_43822647","2.jpg");
        TestCallable t3 = new TestCallable("https://profile.csdnimg.cn/0/8/D/1_weixin_43822647","3.jpg");

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

        //提交执行
        Future<Boolean> r1= ser.submit(t1);
        Future<Boolean> r2= ser.submit(t2);
        Future<Boolean> r3= ser.submit(t3);

        //获取结果
        boolean rs1= r1.get();
        boolean rs2= r2.get();
        boolean rs3= r3.get();

        //关闭服务
        ser.shutdownNow();

    }

}

class WebDownloader{
    //下载方法
    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异常");
        }
    }

二.lambda表达式

package lambda;
/*
推导lambda表达式
*/
public class TestLamda1{

    //3.静态内部类
    static class Like2 implements Ilike{
        @Override
        public void lambda() {
            System.out.println("i like lambda2");
        }
    }

    public static void main(String[] args) {
        Ilike like = new Like();
        like.lambda();

        Ilike like2 = new Like2();
        like2.lambda();

        //4.局部内部类
        class Like3 implements Ilike{
            @Override
            public void lambda() {
                System.out.println("i like lambda3");
            }
        }

        Ilike like3 = new Like3();
        like3.lambda();

        //5.匿名内部类
        like = new Ilike() {
            @Override
            public void lambda() {
                System.out.println("i like lambda4");
            }
        };
        like.lambda();

        //6.用lambda简化
        like = ()->{
            System.out.println("i like lambda5");
        };
        like.lambda();

    }

}

//1.定义一个函数接口(只有一个抽象方法的接口)
interface Ilike{
    void lambda();
}

//2.实现类
class Like implements Ilike{
    @Override
    public void lambda() {
        System.out.println("i like lambda");
    }
}

三.线程状态

1.线程的停止
不推荐使用jdk提供的stop(),destroy()方法,推荐让线程自己停下来,建议使用一个标志位,当flag=false线程终止

package state;

//测试停止线程
//1.建议线程正常停止--->利用次数,不建议死循环
//2.建议使用标志位--->设置一个标志位
//3.不要使用stop或destroy等过时或者JDK不建议使用的方法
public class TestStop implements Runnable{

    //标志位
    boolean flag = true;

    @Override
    public void run(){
        int i=0;
        while(flag){
            System.out.println("run...Thread"+i++);
        }
    }

    //设置一个公开的方法停止线程,装换标志位
    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 < 1000; i++){
            System.out.println("main" + i);
            if(i == 900){
                //调用stop方法切换标志位,让线程停止
                testStop.stop();
                System.out.println("线程停止了");
            }
        }

    }

}

2.线程的休眠
sleep不会释放锁
可以放大问题的发生性,模拟网络延时
可以模拟倒计时

package state;

import demo01.TestThread4;

//模拟网络延时:放大问题的发生性
public class TestSleep implements Runnable {
    //票数
    int ticketNums = 10;

    @Override
    public void run(){
        while(true){
            if(ticketNums <= 0){
                break;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName()+"获得了" + ticketNums-- + "票");

        }
    }

    public static void main(String[] args) {
        TestThread4 testThread4 = new TestThread4();

        new Thread(testThread4, "小明").start();
        new Thread(testThread4, "老师").start();
        new Thread(testThread4, "黄牛").start();

    }
}

3.线程礼让Yield
将线程从运行太转为就绪态

package state;


//测试礼让线程
//礼让不一定成功,看cpu心情
public class TestYield {

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

}

class MyYield implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"线程开始执行");
        Thread.yield(); //礼让
        System.out.println(Thread.currentThread().getName()+"线程停止执行");
    }
}

4.线程强制执行
可以想象为插队,强制一个线程执行直至其结束

package state;

//测试Join方法,想象为插队
public class TestJoin implements Runnable{
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 1000; i++) {
            System.out.println("线程vip来了"+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        //启动线程
        TestJoin testJoin = new TestJoin();
        Thread thread=new Thread(testJoin);
        thread.start();
        for (int i = 0; i < 500; i++) {
            if(i==200){
                thread.join();
            }
            System.out.println("main"+i);
        }
    }
}

5.观测线程状态state
NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED

package state;
//观察线程状态
public class TestState {

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } 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);

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

    }

}

6线程优先级
高优先级的线程更容易执行,但还是要看cpu的心情

package state;

//测试线程的优先级
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);
        Thread t6= new Thread(myPriority);

        //设置优先级,再启动
        t1.start();

        t2.setPriority(1);
        t2.start();

        t3.setPriority(4);
        t3.start();

        t4.setPriority(Thread.MAX_PRIORITY);
        t4.start();

        t5.setPriority(8);
        t5.start();

        t6.setPriority(7);
        t6.start();

    }

}
class MyPriority implements  Runnable{
    @Override
    public void run(){
        System.out.println(Thread.currentThread().getName() + "-->" +Thread.currentThread().getPriority());
    }
}

7.守护线程
虚拟机必须确保用户线程执行完毕,不用等待守护线程执行完毕,守护线程常用来监控内存,垃圾回收,后台记录操作日志

package state;

public class TestDaemon {

    public static void main(String[] args) {
        God god = new God();
        You you = new You();


        Thread thread = new Thread(god);
        thread.setDaemon(true);  //设置守护线程
        thread.start();

        new Thread(you).start(); //用户线程启动

    }

}



//上帝
class God implements Runnable{
    @Override
    public void run() {
        while(true){
            System.out.println("上帝保佑着你");
        }
    }
}


//你
class You implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 36500; i++) {
            System.out.println("开心的活着");
        }
        System.out.println("==============goodebye!world!============");
    }
}