Java 多线程编程

前言

Java 多线程是非常重要的功能,在这记录学习一下。

参考文章:
https://www.runoob.com/java/java-multithreading.html

多线程简介

一个线程完整的生命周期
在这里插入图片描述
Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。

多线程编码

通过实现 Runnable 接口;
通过继承 Thread 类本身;
通过 Callable 和 Future 创建线程

实现 Runnable 接口

代码

package duoxiancheng;
/*
通过实现 Runnable 接口来创建线程
 */
public class TestThread {

    public static void main(String[] args) {
        RunnableDemo r1 = new RunnableDemo("Thread-1");
        r1.start();

        RunnableDemo r2 = new RunnableDemo("Thread-2");
        r2.start();


    }
}

class RunnableDemo implements  Runnable{
    private Thread t ;
    private  String threadName;

    // 构造方法
    RunnableDemo(String name){
        threadName = name ;
        System.out.println("Creating " + threadName);
    }

    @Override
    public void run(){
        System.out.println("Running " + threadName);
        try {
            for (int i = 4; i > 0; i--) {
                System.out.println("Thread: " + threadName + "," + i);
                // 让线程睡眠一会
                Thread.sleep(10);
            }
        }catch (InterruptedException e) {
            System.out.println("Thread " + threadName + " interrupted.");
        }
        System.out.println("Thread " + threadName + " exiting.");
    }

    public void start(){
        System.out.println("Starting " + threadName);
        if(t == null){
            t = new Thread(this,threadName);
            t.start();
        }
    }


}

结果展示:

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1,4
Running Thread-2
Thread: Thread-2,4
Thread: Thread-2,3
Thread: Thread-1,3
Thread: Thread-1,2
Thread: Thread-2,2
Thread: Thread-1,1
Thread: Thread-2,1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

继承 Thread 类

代码:

package duoxiancheng;

public class TestThread01 {

    public static void main(String[] args) {
        ThreadDemo T1 = new ThreadDemo( "Thread-1");
        T1.start();

        ThreadDemo T2 = new ThreadDemo( "Thread-2");
        T2.start();
    }
}

class ThreadDemo extends Thread  {
    private Thread t ;
    private  String threadName;

    // 构造方法
    ThreadDemo(String name){
        threadName = name ;
        System.out.println("Creating " + threadName);
    }

    @Override
    public void run(){
        System.out.println("Running " + threadName);
        try {
            for (int i = 4; i > 0; i--) {
                System.out.println("Thread: " + threadName + "," + i);
                // 让线程睡眠一会
                Thread.sleep(10);
            }
        }catch (InterruptedException e) {
            System.out.println("Thread " + threadName + " interrupted.");
        }
        System.out.println("Thread " + threadName + " exiting.");
    }

    public void start(){
        System.out.println("Starting " + threadName);
        if(t == null){
            t = new Thread(this,threadName);
            t.start();
        }
    }

}

结果展示:

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1,4
Running Thread-2
Thread: Thread-2,4
Thread: Thread-1,3
Thread: Thread-2,3
Thread: Thread-1,2
Thread: Thread-2,2
Thread: Thread-1,1
Thread: Thread-2,1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

Callable 和 Future 创建线程

代码

package duoxiancheng;
/*
通过 Callable 和 Future 创建线程
1. 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
2. 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
3. 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
4. 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值
 */
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestThread0  implements Callable<Integer> {
    public static void main(String[] args) {
        TestThread0 ctt = new TestThread0();
        FutureTask<Integer> ft = new FutureTask<>(ctt);
        for(int i = 0;i < 100;i++)
        {
            System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i);
            if(i==20)
            {
                new Thread(ft,"有返回值的线程").start();
            }
        }
        try
        {
            System.out.println("子线程的返回值:"+ft.get());
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        } catch (ExecutionException e)
        {
            e.printStackTrace();
        }

    }
    @Override
    public Integer call() throws Exception
    {
        int i = 0;
        for(;i<100;i++)
        {
            System.out.println(Thread.currentThread().getName()+" "+i);
        }
        return i;
    }
}

结果展示:

main 的循环变量i的值0
main 的循环变量i的值1
main 的循环变量i的值2
main 的循环变量i的值3
main 的循环变量i的值4
main 的循环变量i的值5
main 的循环变量i的值6
main 的循环变量i的值7
main 的循环变量i的值8
main 的循环变量i的值9
main 的循环变量i的值10
main 的循环变量i的值11
main 的循环变量i的值12
main 的循环变量i的值13
main 的循环变量i的值14
main 的循环变量i的值15
main 的循环变量i的值16
main 的循环变量i的值17
main 的循环变量i的值18
main 的循环变量i的值19
main 的循环变量i的值20
main 的循环变量i的值21
main 的循环变量i的值22
main 的循环变量i的值23
有返回值的线程 0
有返回值的线程 1
有返回值的线程 2
有返回值的线程 3
main 的循环变量i的值24
有返回值的线程 4
main 的循环变量i的值25
main 的循环变量i的值26
有返回值的线程 5
main 的循环变量i的值27
有返回值的线程 6
main 的循环变量i的值28
有返回值的线程 7
main 的循环变量i的值29
有返回值的线程 8
main 的循环变量i的值30
有返回值的线程 9
main 的循环变量i的值31
有返回值的线程 10
有返回值的线程 11
main 的循环变量i的值32
有返回值的线程 12
main 的循环变量i的值33
有返回值的线程 13
有返回值的线程 14
有返回值的线程 15
有返回值的线程 16
有返回值的线程 17
有返回值的线程 18
有返回值的线程 19
有返回值的线程 20
有返回值的线程 21
有返回值的线程 22
有返回值的线程 23
有返回值的线程 24
有返回值的线程 25
有返回值的线程 26
有返回值的线程 27
有返回值的线程 28
有返回值的线程 29
有返回值的线程 30
有返回值的线程 31
有返回值的线程 32
有返回值的线程 33
有返回值的线程 34
有返回值的线程 35
有返回值的线程 36
main 的循环变量i的值34
有返回值的线程 37
main 的循环变量i的值35
有返回值的线程 38
有返回值的线程 39
有返回值的线程 40
有返回值的线程 41
有返回值的线程 42
有返回值的线程 43
有返回值的线程 44
有返回值的线程 45
main 的循环变量i的值36
有返回值的线程 46
有返回值的线程 47
有返回值的线程 48
main 的循环变量i的值37
有返回值的线程 49
有返回值的线程 50
有返回值的线程 51
有返回值的线程 52
有返回值的线程 53
有返回值的线程 54
有返回值的线程 55
有返回值的线程 56
有返回值的线程 57
有返回值的线程 58
有返回值的线程 59
有返回值的线程 60
有返回值的线程 61
有返回值的线程 62
有返回值的线程 63
有返回值的线程 64
有返回值的线程 65
有返回值的线程 66
有返回值的线程 67
有返回值的线程 68
有返回值的线程 69
有返回值的线程 70
有返回值的线程 71
有返回值的线程 72
有返回值的线程 73
有返回值的线程 74
有返回值的线程 75
有返回值的线程 76
有返回值的线程 77
有返回值的线程 78
有返回值的线程 79
有返回值的线程 80
有返回值的线程 81
main 的循环变量i的值38
有返回值的线程 82
有返回值的线程 83
有返回值的线程 84
有返回值的线程 85
有返回值的线程 86
有返回值的线程 87
有返回值的线程 88
有返回值的线程 89
有返回值的线程 90
有返回值的线程 91
有返回值的线程 92
有返回值的线程 93
有返回值的线程 94
有返回值的线程 95
有返回值的线程 96
有返回值的线程 97
有返回值的线程 98
有返回值的线程 99
main 的循环变量i的值39
main 的循环变量i的值40
main 的循环变量i的值41
main 的循环变量i的值42
main 的循环变量i的值43
main 的循环变量i的值44
main 的循环变量i的值45
main 的循环变量i的值46
main 的循环变量i的值47
main 的循环变量i的值48
main 的循环变量i的值49
main 的循环变量i的值50
main 的循环变量i的值51
main 的循环变量i的值52
main 的循环变量i的值53
main 的循环变量i的值54
main 的循环变量i的值55
main 的循环变量i的值56
main 的循环变量i的值57
main 的循环变量i的值58
main 的循环变量i的值59
main 的循环变量i的值60
main 的循环变量i的值61
main 的循环变量i的值62
main 的循环变量i的值63
main 的循环变量i的值64
main 的循环变量i的值65
main 的循环变量i的值66
main 的循环变量i的值67
main 的循环变量i的值68
main 的循环变量i的值69
main 的循环变量i的值70
main 的循环变量i的值71
main 的循环变量i的值72
main 的循环变量i的值73
main 的循环变量i的值74
main 的循环变量i的值75
main 的循环变量i的值76
main 的循环变量i的值77
main 的循环变量i的值78
main 的循环变量i的值79
main 的循环变量i的值80
main 的循环变量i的值81
main 的循环变量i的值82
main 的循环变量i的值83
main 的循环变量i的值84
main 的循环变量i的值85
main 的循环变量i的值86
main 的循环变量i的值87
main 的循环变量i的值88
main 的循环变量i的值89
main 的循环变量i的值90
main 的循环变量i的值91
main 的循环变量i的值92
main 的循环变量i的值93
main 的循环变量i的值94
main 的循环变量i的值95
main 的循环变量i的值96
main 的循环变量i的值97
main 的循环变量i的值98
main 的循环变量i的值99
子线程的返回值:100

总结

  • 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类
  • 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。
  • 有效利用多线程的关键是理解程序是并发执行而不是串行执行的。例如:程序中有两个子系统需要并发执行,这时候就需要利用多线程编程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nsq_ai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值