zoukankan      html  css  js  c++  java
  • Java:多线程,分别用Thread、Runnable、Callable实现线程

    并发性(concurrency)和并行性(parallel)是两个概念,并行是指在同一时刻,有多条指令在多个处理器上同时执行;并发指在同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,使得宏观上具有多个进程同时执行的效果。

    多线程编程优点:

    1. 进程之间不能共享内存,但线程之间共享内存非常容易。
    2. 系统创建线程所分配的资源相对创建进程而言,代价非常小。

    Java中实现线程的方式目前有三种:

    一:继承Thread类创建线程类

    package com.clzhang.sample.thread;
    
    // 通过继承Thread类来创建线程类
    public class ThreadByExtends extends Thread {
        private int i;
    
        @Override
        public void run() {
            // 当线程类继承Thread类时,直接使用this即可获取当前线程句柄。
            // 因此可以直接调用getName()方法返回当前线程的名称。
            System.out.println("当前线程名称是:" + getName());
    
            for (; i < 5; i++) {
                System.out.println(getName() + ":" + i);
                try {
                    // 保证让别的线程也有执行的机会
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                }
            }
        }
    
        public static void main(String[] args) {
            // 静态方法没有this,只能通过Thread.currentThread获取当前线程句柄
            System.out.println(Thread.currentThread().getName());
            
            // 创建、并启动第一条线程
            new ThreadByExtends().start();
            // 创建、并启动第二条线程
            new ThreadByExtends().start();
        }
    }

    输出:

    main
    当前线程名称是:Thread-0
    Thread-0:0
    当前线程名称是:Thread-1
    Thread-1:0
    Thread-0:1
    Thread-1:1
    Thread-1:2
    Thread-0:2
    Thread-1:3
    Thread-0:3
    Thread-0:4
    Thread-1:4

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

    package com.clzhang.sample.thread;
    
    /**
     * 通过实现Runnable接口来创建线程类
     * 1.Runnable非常适合多个相同线程来处理同一份资源的情况
     * 2.Runnable可以避免由于Java的单继承机制带来的局限
     * 3.如果想获取当前线程句柄,只能用Thread.currentThread()方法
     */
    public class ThreadByRunnable implements Runnable {
        private int i;
    
        @Override
        public void run() {
            System.out.println("当前线程名称是:" + Thread.currentThread().getName());
    
            for (; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + ":" + i);
    
                try {
                    // 因为sleep是静态方法,所以不需要通过Thread.currentThread()方法获取当前线程句柄
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                }
            }
        }
    
        public static void main(String[] args) {
            ThreadByRunnable st = new ThreadByRunnable();
            new Thread(st, "新线程1").start();
            new Thread(st, "新线程2").start();
        }
    }

    输出:

    当前线程名称是:新线程1
    当前线程名称是:新线程2
    新线程2:0
    新线程1:0
    新线程2:2
    新线程1:2
    新线程2:3
    新线程1:4

    三:使用Calable和Future创建具备返回值的线程

    package com.clzhang.sample.thread;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.FutureTask;
    
    // 实现Callable接口来实现线程
    public class ThreadByCallable implements Callable<Integer> {
        
        @Override
        public Integer call() {
            System.out.println("当前线程名称是:" + Thread.currentThread().getName());
    
            int i = 0;
            for (; i < 5; i++) {
                System.out.println("循环变量i的值:" + i);
            }
            
            // call()方法有返回值
            return i;
        }
    
        public static void main(String[] args) {
            ThreadByCallable rt = new ThreadByCallable();
    
            // 使用FutureTask来包装Callable对象
            FutureTask<Integer> task = new FutureTask<Integer>(rt);
            new Thread(task, "有返回值的线程").start();
            try {
                // 获取线程返回值
                System.out.println("子线程的返回值:" + task.get());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    输出:

    当前线程名称是:有返回值的线程
    循环变量i的值:0
    循环变量i的值:1
    循环变量i的值:2
    循环变量i的值:3
    循环变量i的值:4
    子线程的返回值:5

    总结

    用Runnable与Callable接口的方式创建多线程的特点:

    1. 线程类只是实现了Runnable接口或Callable接口,还可以继承其它类。
    2. 在这种方式下,多个线程可以共享一个target对象,所以非常适合多个线程来处理同一份资源情况。
    3. 如果需要访问当前线程,需要使用Thread.currentThread方法。
    4. Callable接口与Runnable接口相比,只是Callable接口可以返回值而已。

    用Thread类的方式创建多线程的特点:

    1. 因为线程已经继承Thread类,所以不可以再继承其它类。
    2. 如果需要访问当前线程,直接使用this即可。
  • 相关阅读:
    POJ 2486
    奇怪的电梯
    穿越泥地(mud)
    救援行动(save)
    As Fast As Possible
    Connecting Universities
    They Are Everywhere
    Cells Not Under Attack
    吃饭
    花店橱窗(flower)
  • 原文地址:https://www.cnblogs.com/nayitian/p/3258377.html
Copyright © 2011-2022 走看看