线程的状态以及Callable接口的使用

一、线程的状态

在这里插入图片描述
线程有新建状态、就绪状态,运行状态、阻塞状态,死亡状态,当线程执行完所有的代码或者interrupt中断后,就进入死亡状态,此时如果再调用start方法就会抛出异常,其中阻塞状态的线程不会释放锁。

  1. public class TestState {
  2. public static void main(String[] args) throws InterruptedException {
  3. Thread thread = new Thread(() -> {
  4. for (int i = 0; i < 5; i++) {
  5. try {
  6. Thread.sleep(600L);
  7. } catch (InterruptedException e) {
  8. e.printStackTrace();
  9. }
  10. System.out.println(Thread.currentThread().getName() + i);
  11. }
  12. });
  13. //查看状态
  14. Thread.State state = thread.getState();
  15. System.out.println( " - " + state);
  16. thread.start(); //线程就绪
  17. state = thread.getState();
  18. System.out.println(" -- " + state);
  19. while (state != Thread.State.TERMINATED){
  20. state = thread.getState();
  21. Thread.sleep(100L);
  22. System.out.println(" --- " + state);
  23. }
  24. //执行到这里的时候 线程已经死亡,如果再start就会抛出异常
  25. thread.start(); //IllegalThreadStateException
  26. }
  27. }

运行查看控制台
在这里插入图片描述
在这里插入图片描述
可以看到创建但没调用 start方法前为new新建状态,如果如果调用了start方法则进入就绪状态,此时会等待CPU的调度,当调用sleep方法时,线程就成为了阻塞状态,最后进入TERMINATED终结状态,当线程进入终结状态,如果再调用start就会抛出IllegalThreadStateException异常。

二、Callable接口的使用

创建多线程的方式通常有继承Thread类和实现Runnable接口,除了这两种还有实现Callable接口

  1. public class MyCallable implements Callable<Object> {
  2. @Override
  3. public Object call() throws Exception {
  4. for (int i = 0;i < 20;i++){
  5. System.out.println(Thread.currentThread().getName() + " ---> " +i);
  6. }
  7. return UUID.randomUUID().toString();
  8. }
  9. public static void main(String[] args) throws ExecutionException, InterruptedException {
  10. MyCallable myCallable1 = new MyCallable();
  11. MyCallable myCallable2 = new MyCallable();
  12. MyCallable myCallable3 = new MyCallable();
  13. //创建执行服务
  14. ExecutorService executorService = Executors.newFixedThreadPool(3);
  15. Future<Object> submit1 = executorService.submit(myCallable1);
  16. Future<Object> submit2 = executorService.submit(myCallable2);
  17. Future<Object> submit3 = executorService.submit(myCallable3);
  18. System.out.println(submit1.get());
  19. System.out.println(submit2.get());
  20. System.out.println(submit3.get());
  21. executorService.shutdown();
  22. }
  23. }

实现Callable接口的好处有自定义线程的返回值类型,可抛出异常
也可以使用集合的方法并发执行

  1. public class MyCallable2 implements Callable<Object> {
  2. @Override
  3. public Object call() throws Exception {
  4. for (int i = 0;i < 20;i++){
  5. System.out.println(Thread.currentThread().getName() + " ---> " +i);
  6. }
  7. return UUID.randomUUID().toString();
  8. }
  9. public static void main(String[] args) throws ExecutionException, InterruptedException {
  10. List<MyCallable2> list = new ArrayList<>();
  11. MyCallable2 myCallable1 = new MyCallable2();
  12. MyCallable2 myCallable2 = new MyCallable2();
  13. MyCallable2 myCallable3 = new MyCallable2();
  14. //创建执行服务
  15. ExecutorService executorService = Executors.newFixedThreadPool(3);
  16. list.add(myCallable1);
  17. list.add(myCallable2);
  18. list.add(myCallable3);
  19. List<Future<Object>> futures = executorService.invokeAll(list);
  20. for (Future<Object> future : futures) {
  21. System.out.println(future.get());
  22. }
  23. executorService.shutdown();
  24. }
  25. }

发表评论

表情:
评论列表 (有 0 条评论,44人围观)

还没有评论,来说两句吧...

相关阅读