java基础-线程状态分析

141 阅读2分钟

一. 线程初体验

java实现一个线程最基本就3种方式(其他的都是通过这几个衍生出来)

1.继承Thread类(实现了Runnable接口),重写run方法(Runnable的方法)

2.实现Runnable接口,重写run方法

3.实现Callable(函数式接口),重写call方法,有回调

方法1:

public class ThreadOne extends Thread {
    @Override
    public void run() {
        System.out.println("当前线程是:" + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        System.out.println("主线程是:" + Thread.currentThread().getName());
        new ThreadOne().start();
    }
}

image.png

我们通过start启动一个新的线程,看start方法可以看到,会执行已和native方法(屏蔽jvm执行平台的差异),private native void start0(),用c++编写,最终会在回调我们重写的run方法,在方法2可以看到

方法2:

public class ThreadTwo implements Runnable {
    @Override
    public void run() {
        System.out.println("Runnable当前线程是:" + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        System.out.println("Runnable主线程是:" + Thread.currentThread().getName());
        new Thread(new ThreadTwo()).start();
    }
}

执行runnable的方法

image.png

image.png

方法3:

public class ThreadThree implements Callable {
    @Override
    public Object call() throws Exception {
        System.out.println("Callable当前线程是:" + Thread.currentThread().getName());
        return "success";
    }

![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f2702c8774b0431d8939f8b44b1eff12~tplv-k3u1fbpfcp-watermark.image?)
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService  executorService = Executors.newFixedThreadPool(1);
        System.out.println("Callable当前线程是:" + Thread.currentThread().getName());
        //带执行结果的
        Future future = executorService.submit(new ThreadThree());
        future.get();
    }
}

这里涉及线程池后面文章会详细讲。

二. 线程状态

通过看jdk1.8 Thread.State枚举类 线程有6个状态,其中图中Runnable可以人为的划分为Ready和Running

线程状态的转换如上图,各步骤触发的条件如下:

image.png 步骤1:new Thread.start()

步骤2:Thread.yield()会让出cpu,Running到Ready状态

步骤3:interrupt中断

步骤4:Object.wait(time),Object.join(time),Theaad.sleep(time),LockSupport.parkNanos(time); LockSupport.parkUntil(time);

步骤5:Object.wait(),Object.join(),LockSupport.park()

步骤6:synchronized

上面典型的演示下:

sleep后,timed_waiting状态

public class ThreadOne extends Thread {
    @Override
    public void run() {
        System.out.println("当前线程是:" + Thread.currentThread().getName());
        try {
            sleep(2000);
            System.out.println(Thread.currentThread().getName() +
                    "睡眠结束后状态是:" + Thread.currentThread().getState());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println("主线程是:" + Thread.currentThread().getName());

        ThreadOne threadOne = new ThreadOne();
        threadOne.start();
        State state1 = threadOne.getState();
        System.out.println(threadOne.getName() + "初始状态是:" + state1);
        try {
            //主线程睡眠时间小于子线程
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(threadOne.getName() + "睡眠状态是:" + threadOne.getState());
    }
}

image.png

join(join最终会调用Object.wait)后,通过打断点的方式,主线程进入waiting状态

image.png

public class ThreadOne extends Thread {
    @Override
    public void run() {
        System.out.println("当前线程是:" + Thread.currentThread().getName());
        try {
            sleep(2000);
            System.out.println();
            sleep(2000);
            System.out.println(Thread.currentThread().getName() +
                    "睡眠结束后状态是:" + Thread.currentThread().getState());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        System.out.println("主线程是:" + Thread.currentThread().getName());

        ThreadOne threadOne = new ThreadOne();
        threadOne.start();
        threadOne.join();
        System.out.println("结束了");
    }
}

synchronized后,线程进入blocked状态

public class ThreadOne extends Thread {
    private Object object;

    ThreadOne(Object o) {
        object = o;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "状态是:" + Thread.currentThread().getState());
        synchronized (object) {
            try {
                //让其他线程获取不到锁
                sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) throws InterruptedException {
        System.out.println("主线程是:" + Thread.currentThread().getName());
        Object object = new Object();
        ThreadOne threadOne = new ThreadOne(object);
        threadOne.start();
        sleep(500);
        ThreadOne threadTwo = new ThreadOne(object);
        threadTwo.start();
        sleep(500);
        System.out.println(threadOne.getName() + "状态是:" +
                threadOne.getState());
        System.out.println(threadTwo.getName() + "状态是:" +
                threadTwo.getState());
    }
}

image.png