zoukankan      html  css  js  c++  java
  • (二)多线程:线程的创建和启动

    Java使用Thread类代表线程,所有线程对象都必须是Thread类或其子类的实例,每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码)。Java使用线程执行体来代表这段程序流。

    一.继承Thread类创建线程类

    1.定义Thread的子类,并重写该类的run()方法,改run()方法的方法体就代表了线程需要完成的任务。因此把run()方法称为线程执行体。

    2.创建Thread子类的实例,即创建子线程对象。

    3.调用线程对象的start()方法来启动该线程。

    示例代码:

    public class FirstThread extends Thread{
    
         @Override
         public void run() {
             for (int i = 0; i < 100; i++) {
                 System.out.println(getName() + "...");
             }
         }
    
         public static void main(String[] args) {
             FirstThread t1 = new FirstThread();
             t1.setName("t1");
             FirstThread t2 = new FirstThread();
             t2.setName("t2");
             for (int i = 0; i < 100; i++) {
                 if (i == 20) {
                     t1.start();
                     t2.start();
                 }
                 System.out.println("main...");
             }
    
         }
     }
    

    二.实现Runnable接口创建线程类

    1.定义Runnable接口的实现类,并重写该接口run()方法,该run()方法的方法体同样是该线程的线程执行体。

    2.创建Runnable实现类的实体,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

    示例代码:

    public class FirstRunnableThread implements Runnable {
    
     private int i;
    
     @Override
     public void run() {
         for (; i < 100; i++) {
             System.out.println(Thread.currentThread().getName() + "..." + i);
         }
     }
    
     public static void main(String[] args) {
         FirstRunnableThread r = new FirstRunnableThread();
         Thread t1 = new Thread(r, "t1");
         Thread t2 = new Thread(r, "t2");
         for (int i = 0; i < 100; i++) {
             if (i == 20) {
                 t1.start();
                 t2.start();
             }
             System.out.println("mian...");
         }
     }
    }
    

    三.使用Callable和Future创建线程

    Callable接口可以提供一个call()方法作为线程执行体,但call()方法比run()方法功能更强大。

    1.call()方法可以有返回值。

    2.call()方法可以声明抛出异常

    示例代码:

    public class FirstCallableThread {
    
     public static void main(String[] args) {
    
         //创建Callable对象
         FirstCallableThread ct = new FirstCallableThread();
         //使用FutureTask来包装Callable
         FutureTask<Integer> futureTask = new FutureTask<>((Callable<Integer>) () -> {
             int i = 0;
             for (; i < 100; i++) {
                 System.out.println(Thread.currentThread().getName() + "..." + i);
             }
             return i;
         });
    
         for (int i = 0; i < 100; i++) {
             System.out.println(Thread.currentThread().getName() + "...i:" + i);
             if (i == 20) {
                 //实质还是用Callable来创建并启动线程
                 new Thread(futureTask, "有返回值的线程").start();
             }
         }
    
         try {
             System.out.println("子线程的返回值:" + futureTask.get());
         } catch (InterruptedException e) {
             e.printStackTrace();
         } catch (ExecutionException e) {
             e.printStackTrace();
         }
      }
    }
    

    四.创建线程的三种方式对比

    实现Runnable接口与实现Callable接口实现多线程的方式基本相同,只是Callable接口定义有返回值,可以声明抛出异常而已。
    1.线程类只是实现Runnable接口或Callable接口,还可以继承其他类。

    2.在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理通一份资源的情况,从而可以将CPU,代码和数据分开,形成清晰的模式,较好的提现了面向对象的思想。

    3.劣势是,编程稍稍复杂。

    采用继承Thread类的方式创建多线程的优缺点:
    1.劣势是,因为线程类已经继承了Thread类,所以不能再继承其他父类。

    2.优势是,编写简单,this即可获得当前线程。

    因此一般推荐采用实现Runnable接口,Callable接口的方式来创建线程。

    文章内容均取自《疯狂Java讲义-李刚》一书中多线程章节。截取重要知识点作为笔记记录,方便自己回顾。

  • 相关阅读:
    Hibernate的游离态与持久态转换
    怎样区分直连串口线和交叉串口线?
    JAVA 内存泄露的理解
    leetcode第一刷_Validate Binary Search Tree
    Java程序猿的JavaScript学习笔记(8——jQuery选择器)
    Android二维码开源项目zxing用例简化和生成二维码、条形码
    Android Service 服务(一)—— Service
    一个简单的文本编辑器。(是在DEV C++下写的)
    我的Hook学习笔记
    ios网络学习------8 xml格式数据的请求处理 用代码块封装
  • 原文地址:https://www.cnblogs.com/everyingo/p/12781030.html
Copyright © 2011-2022 走看看