Java多线程之基础篇

一、概述1.1 进程与线程进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。进程实体由程序段, 数据段, PCB(进程控制块)组成。线程可以看做轻量级进程,线程是进程的执行单元,是进程调度的基本单位。每一个进程都是拥有一个独立的内存空间的应用程序,线程是进程中的一个执行路径,共享一个内存空间(拥有自己的栈空间,共享堆内存),线程之间可以自由切换,并发执行。1.2 线程的调度分时调度所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。抢占式调
摘要由CSDN通过智能技术生成

一、概述

1.1 进程与线程

进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。进程实体由程序段, 数据段, PCB(进程控制块)组成。

线程可以看做轻量级进程,线程是进程的执行单元,是进程调度的基本单位。

每一个进程都是拥有一个独立的内存空间的应用程序,线程是进程中的一个执行路径,共享一个内存空间(拥有自己的栈空间,共享堆内存),线程之间可以自由切换,并发执行。

1.2 线程的调度

  • 分时调度
    所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。

  • 抢占式调度
    Java使用的是抢占式调度,哪个线程抢到时间片,哪个线程就执行,程序员可以设置线程的优先级,提高此线程抢占时间片的概率,如果线程的优先级相同,那么会随机选择一个(线程随机性)。

  • CPU使用抢占式调度在多个线程间进行告诉的切换,对于CPU的一个核心而言,某个时刻只能执行一个线程,而CPU在多个线程间切换的速度很快,看上去就像是同时在进行。其实,多线程并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的使用率更高。

1.3同步与异步&并发与并行

同步:排队执行,效率低但安全。
异步:同时执行,效率高但是数据不安全。
并发性(concurrency)和并行性(parallel):并行是指在同一时刻,有多条指令同时运行;并发指的是在同一个时间段,有多条指令同时运行,在同一时刻只能有一条指令执行,即每个指令以时间片为单位来执行。

二、Java创建线程的方法

2.1 继承Thread

main方法

public class Demo1 {
   
    public static void main(String[] args) throws InterruptedException {
   
        MyThread m = new MyThread();
        m.start();
        for(int i = 0;i < 10;i++){
   
            System.out.println(":汗滴禾下土" + i);
        }
    }
}

线程

public class MyThread extends Thread {
   
    /**
     * run方法就是线程要执行的任务方法
     */
    @Override
    public void run() {
   
        //这里的代码就是一条执行路径
        //这个执行路径的触发方法不是调用run方法,而是通过thread对象的start()方法来启动任务
        for(int i = 0;i < 10;i++){
   
            System.out.println(":锄禾日当午" + i);
        }
    }
}

运行结果
在这里插入图片描述

  • 若该线程只用一次,可以使用匿名内部类创建线程非常简单。
public class Demo1 {
   
    public static void main(String[] args) {
   
        new Thread(){
   
            @Override
            public void run() {
   
                for(int i = 0;i<10;i++){
   
                    System.out.println(":锄禾日当午" + i);
                }
            }
        }.start();
        for(int i = 0;i<10;i++){
   
            System.out.println(":汗滴禾下土" + i);
        }
    }
}
  • 也可以使用Lambda表达式方法创建
public class Demo1 {
   
    public static void main(String[] args) {
   
        new Thread(() -> {
   
            for(int i = 0;i<10;i++){
   
                System.out.println(":锄禾日当午" + i);
            }
        }).start();
        for(int i = 0;i<10;i++){
   
            System.out.println(":汗滴禾下土" + i);
        }
    }
}

2.2 实现Runnable

main方法

public class Demo1 {
   
    public static void main(String[] args) throws InterruptedException {
   
        MyRunnable r = new MyRunnable();
        Thread t = new Thread(r);
        t.start();
        for(int i = 0;i < 10;i++){
   
            System.out.println(":汗滴禾下土" + i);
        }
    }
}

线程

public class MyRunnable implements Runnable {
   

    @Override
    public void run() {
   
        for (int i = 0; i < 10; i++) {
   
            System.out.println(":锄禾日当午" + i);
        }
    }
}

与继承Thread相比,有以下的优势

  • 1、通过创建任务,然后给线程分配的方式来实现的多线程,更适合多个线程同时执行相同的任务。
  • 2、避免了Java单继承带来的局限性。
  • 3、 任务与线程本身是分离的,提高了程序的健壮性。
  • 4、线程池技术,接收Runnable类型的任务,不接收Thread类型的线程。

2.3 实现Callable接口通过FutureTask包装器来创建Thread线程

  • 步骤1:编写类实现Callable接口,实现call方法
class XXX implemnts Callable<T> {
   
	 @Override
    public T call() throws Exception{
   
        return T;
    }
}
  • 步骤2:创建FutureTask对象,并传入Callable对象
FutureTask<T> futureTask = new FutureTask<>(callable);
  • 步骤3:通过Thread启动线程
new Thread(futureTask).start();

2.3.1 FutureTask类的方法

  • V get() 如果需要等待计算完成,然后检索其结果。
    调用这个方法,主线程将会等待子线程执行完毕再执行。
  • V get​(long timeout, TimeUnit unit) 如果需要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。
    调用这个方法,主线程会等待子线程执行完毕,传入参数为时间,在指定时间内没有得到结果,主线程就不再等待结果返回。
  • boolean isDone() 检查线程是否结束

示例(如不加get方法,主线程和子线程同时进行)


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值