Java基础【重点】多线程—— 线程创建

一、线程
1、线程是什么?
线程(thread)是一个程序内部的一条执行路径。
我们之前启动程序执行后,main方法的执行其实就是一条单独的执行路径。

public static void main(String[] args) {
// 代码…    
for (int i = 0; i < 10; i++) { 
	System.out.println(i);    
}    
// 代码...
}

程序中如果只有一条执行路径,那么这个程序就是单线程的程序。

2、多线程是什么?
多线程是指从软硬件上实现多条执行流程的技术。

多线程用在哪里,有什么好处?
在这里插入图片描述

再例如:消息通信、淘宝、京东系统都离不开多线程技术。提高了办事效率。

3、关于多线程需要学会什么

在这里插入图片描述

二、多线程的创建

Thread类

  1. Java是通过java.lang.Thread 类来代表线程的。
  2. 按照面向对象的思想,Thread类应该提供了实现多线程的方式。
    当有很多线程在执行的时候,我们怎么去区分这些线程呢?
    此时需要使用Thread的常用方法:getName()、setName()、currentThread()等。
    ① Thread获取和设置线程名称
    在这里插入图片描述

② Thread类获得当前线程的对象
在这里插入图片描述

注意!!
1、此方法是Thread类的静态方法,可以直接使用Thread类调用。
2、这个方法是在哪个线程执行中调用的,就会得到哪个线程对象。

③ Thread的构造器
在这里插入图片描述

④ Thread类的线程休眠方法
在这里插入图片描述

总结
Thread常用方法
在这里插入图片描述

Thread构造器
在这里插入图片描述

1、多线程的实现方案一:继承Thread类

  1. 定义一个子类MyThread继承线程类java.lang.Thread,重写run()方法
  2. 创建MyThread类的对象
  3. 调用线程对象的start()方法启动线程(启动后还是执行run方法的)

方式一优缺点:
优点:编码简单
缺点:线程类已经继承Thread,无法继承其他类,不利于扩展

代码测试
我的线程类

package ThreadTest;  
  
public class MyThread2 extends Thread {  
    @Override  
    public void run() {  
        for (int i = 0; i < 10; i++) {  
            System.out.println("MyThread:"+i);  
        }  
        test();  
    }  
    public void test(){  
        System.out.println("1111111");  
    }  
}

多线程测试

package ThreadTest;  
  
public class ThreadTest2 {  
    public static void main(String[] args) {  
        // 创建多线程方式1 继承Thread类  
        Thread my = new MyThread2();  
        my.start();// start 表示的是启动当前线程  
        for (int i = 0; i < 20; i++) {  
            System.out.println("ThreadTest:"+i);  
        }  
    }  
}

2、多线程的实现方案二:实现Runnable接口

  1. 定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法
  2. 创建MyRunnable任务对象
  3. 把MyRunnable任务对象交给Thread处理。
  4. 调用线程对象的start()方法启动线程

Thread的构造器
在这里插入图片描述

方式二优缺点:
优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的。

多线程的实现方案二:实现Runnable接口(匿名内部类形式)

  • 可以创建Runnable的匿名内部类对象。
  • 交给Thread处理。
  • 调用线程对象的start()启动线程。

代码测试

package ThreadTest;  
  
public class ThreadTest3 {  
    public static void main(String[] args) {
//       方式一  
//        MyRunnable my = new MyRunnable(); 
//       方式二 1.使用匿名内部类  2.lamda表达式
        Thread thread = new Thread(()->{  
  
            for (int i = 0; i < 100; i++) {  
            System.out.println(Thread.currentThread().getName()+i);  
        }  
    },"蓝鸟");  
        thread.start();  
        MyThread2 myThread2 = new MyThread2("青鸟");  
        myThread2.start();  
    }  
}  
//class MyRunnable implements Runnable{  
//  
//    @Override  
//    public void run() {  
//        for (int i = 0; i < 10; i++) {  
//            System.out.println("MyRunnable"+i);  
//        }  
//    }  
//}

3、多线程的实现方案三:利用Callable、FutureTask接口实现。

  1. 得到任务对象
  • 定义类实现Callable接口,重写call方法,封装要做的事情。
  • 用FutureTask把Callable对象封装成线程任务对象。
  1. 把线程任务对象交给Thread处理。
  2. 调用Thread的start方法启动线程,执行任务
  3. 线程执行完毕后、通过FutureTask的get方法去获取任务执行的结果。
    FutureTask的API
    在这里插入图片描述

方式三优缺点:

  • 优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
    可以在线程执行完毕后去获取线程执行的结果。
  • 缺点:编码复杂一点。

代码测试

package ThreadTest;  
  
import java.util.concurrent.Callable;  
import java.util.concurrent.ExecutionException;  
import java.util.concurrent.FutureTask;  
  
public class ThreadTest4 {  
    /**  
     *      使用的是  Callable FutureTask  
     *      1.创建任务对象  
     *      ①  
     *      ②     *     *      
	 *      2.把任务 交给线程来处理  
     *      3.启动线程  
     *      4.获取线程执行结果  
     *  
     * */    public static void main(String[] args) throws ExecutionException, InterruptedException {  
        MyCallable call = new MyCallable();  
        FutureTask<String> task = new FutureTask<>(call);  
        Thread thread = new Thread(task);  
        thread.start();  
        int s = getSum();  
        System.out.println(Thread.currentThread().getName()+":"+s);  
//        Object obj = task.get();  
//        System.out.println(obj);  
        Integer sum1 = Integer.parseInt((String)task.get());// task.get() 调用此方法就会等到任务执行完毕  
        System.out.println("最终的结果是:"+(s+sum1));  
        System.out.println(1111111111111111L);  
        System.out.println(66666666666666L);  
    }  
    public static int getSum(){  
        int s = 0;  
        for (int i = 0; i < 200; i++) {  
            s+=i;  
        }  
        return s;  
    }  
}  
class MyCallable implements Callable<String>{  
    @Override  
    public String call() throws Exception {  
        int s = sum();  
        System.out.println(Thread.currentThread().getName()+":"+s);  
        return String.valueOf(s);  
    }  
    public int sum(){  
        int s = 0;  
        for (int i = 1; i <= 100; i++) {  
            s+=i;  
        }  
        return s;  
    }  
}

三、总结

3种方式对比
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

狂神我的神

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

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

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

打赏作者

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

抵扣说明:

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

余额充值