Java学习之多线程

       今天给大家分享的是我Java学习中多线程的学习部分。

       首先大家肯定都有一个问题:什么是多线程?为什么要使用多线程?在这里我就给大家讲解一下。而要说起多线程,就不得不说一下什么是线程和进程。

什么是进程、线程、多线程?

        目前我们所熟知的操作系统Windows、Unixs、Linux系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程多线程就是指一个进程中同时有多个执行路径(线程)正在执行。

为什么要使用多线程(多线程的优点)?

  • 进程之间不能共享内存,但线程之间共享内存非常容易。
  • 系统创建进程是需要为该进程重新分配系统资源,但创建线程则代价小得多,因此使用多线程来实现多任务并发比多进程的效率高。
  • Java语言内置了多线程功能支持,而不是单纯的作为底层操作系统的调度方式,从而简化了Java的多线程编程。

继承Thread类来创建线程类

通过继承Thread类来创建并启动多线程分为以下几步:

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

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

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

Test类:

package com.langsin.thread;

public class Test {

    public static void main(String[] args) {
        /*
         *main方法:主线程,打印1-100的数字
         *创建一个线程,打印1-100的数字
         */
        ThreadDemo demo = new ThreadDemo("线程A");	//创建线程后,再启动线程,线程就单独去运行了
        demo.start();
        String threadName = Thread.currentThread().getName();	//获取当前运行线程,即main线程的名称
        for(int i=1; i<=100; i++) {
            System.out.println("当前线程:" + threadName + ",进行输出值" + i);
        }
    }

}

ThreadDemo类:

package com.langsin.thread;

public class ThreadDemo extends Thread {
    public ThreadDemo(String name) {
        this.setName(name);
    }

    public void run() {
        for(int i=0; i<100; i++) {
            System.out.println("当前线程:" + this.getName() + ",输出了数值:" + i);
        }
    }
}

下面是运行结果的部分截图,体现出了线程是抢占式运行。

在上述代码中,学习了线程的两个方法:

  • Thread.currentThread():该方法返回当前正在执行的线程对象
  • getName():返回对象线程的名称

实现Runnable接口创建类

实现Runnable接口,创建并启动多线程的步骤如下:

  1. 定义Runnable接口的实现类,并重写该接口的run方法,该run方法的方法体同样是该线程的线程执行体
  2. 创建Runnable实现类的实例对象,并以此实例对象作为Thread的target来创建Thread类,该Thread对象才是真正的线程对象。
  3. 调用线程对象的start()方法来启动该线程。

Test类:

package com.langsin.thread;

public class Test {

    public static void main(String[] args) {
        RunableDemo target = new RunableDemo();		//任务体
        Thread thread = new Thread(target, "线程A");
        thread.start();
        String threadName = Thread.currentThread().getName();	//获取main线程的名称
        for(int i=1; i<=100; i++) {
	        System.out.println("当前线程:" + threadName + ",进行输出值" + i);
        }
    }

}

RunableDemo类:

package com.langsin.thread;

public class RunableDemo implements Runnable {
    public void run() {
        //Runable实际上并不是创建一个线程类,只是一个线程的任务体
        String name = Thread.currentThread().getName();
        for(int i=0; i<100; i++) {
            System.out.println("当前线程:" + name + ",输出了数值:" + i);
        }
    }
}

使用Callable和Future创建线程

创建并启动有返回值的线程的步骤如下:

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

Test类:

package com.langsin.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

public class Test {
    public static void main(String[] args) throws Exception {
    Callable<Integer> callable = new Callable<Integer>() {
        public Integer call() throws Exception {
            int a = 3;
            int b = 5;
            Thread.sleep(2000);
            return a + b;
        }
    };
    FutureTask<Integer> task = new FutureTask<>(callable);
    Thread thread = new Thread(task);
    thread.start();
    //通过task获取返回的结果值
    Integer value = task.get(3,TimeUnit.SECONDS);	//阻塞式方法,设置等待3秒后获取。若设置等待时间小于休息时间,则报错
    System.out.println(value);
    }
}

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

       通过继承Thread类或实现Runnable、Callable接口都可以实现多线程,不过实现Runnable接口与实现Callable接口的方式基本相同,只是Callable接口里定义的方法有返回值,可以声明抛出异常,Callable需要FutureTask来进行封装成Thread可识别的target目标。因此可以将实现Runnable接口和实现Callable接口归纳为一种方式。这种方式与继承Thread方式之间的主要差别如下:

采用Runnable、Callable接口的方式创建多线程:

  • 线程类只是实现了Runnable接口或Callable接口,还可以继承其他类
  • 多个线程可以共享一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好的体现了面向对象的思想。
  • 劣势:编程稍微复杂,如果需要访问当前线程,则必须使用Thread.currentThread()方法。

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

  • 编写简单,如果需要访问当前线程,直接使用this即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值