java笔记 - 线程创建

一、创建线程的方法

1.继承Thread类

实现步骤:
(1)创建一个继承于Thread类的子类
(2)重写Thread类的run()方法【线程执行的操作声明在run()中】
(3)创建Thread类的子类的对象
(4)通过此对象调用start()方法【①启动线程②调用当前线程对象的run方法】
代码

//(1)创建一个继承于Thread类的子类
class MyThread1 extends Thread{
    public MyThread1(String name){
        super(name);
    }
		//(2)重写Thread类的run()方法
    @Override
    public void run() {
        System.out.println("第一种创建线程");
        }
    }
}
public class ThreadTest{
    public static void main(String[] args) {
		//(3)创建Thread类的子类的对象
        MyThread1 t1=new MyThread1();
		//(4)通过此对象调用start()方法
        t1.start();
		}
}

2.实现Runnable接口

打破第一种单继承Thread类的局限
实现步骤
(1)创建一个实现了Runnable接口的类
(2)该实现类 去实现Runnable中的抽象方法run()
(3)创建实现类的对象
(4)将此对象作为参数传递到Thread类的构造器中,创建 Thread类的对象
【Thread构造方法源码:public Thread(Runnable target)】
(5)通过Thread类的对象调用start()
代码

//1.创建一个实现了Runnable接口的类
class MyThread2 implements Runnable{
    @Override
    //2.实现类去实现Runnable中的抽象方法run()
    public void run() {
        System.out.println("第二种创建线程:实现Runnable接口");
            }
     }
		 public class ThreadTest1 {
    public static void main(String[] args) {
        //3.创建实现类的对象
        MyThread2 m=new MyThread2();
        // 4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
        Thread thread = new Thread(m);
        // 5.通过Thread类的对象调用start()
         thread.start();

或者使用匿名内部类定义接口对象

public class MyRunnalbe{
	public static void main(String[] args){
		new Thread(new Runnable(){
			@Override
			public void run(){
				System.out.println("Hello");
			}
		}).start()
	}
}

3、实现Callable接口,重写call方法

callcable接口有返回值

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

 class Mycallable implements Callable<String> {
    private int ticket=10;
    @Override
    public String call() throws Exception{
        while (this.ticket>0){
            System.out.println("剩余票数="+this.ticket--);
        }
        return "票卖完了";
    }
}
public class Mythread1 {
    public static void main(String[] args) throws InterruptedException ,ExecutionException{
        FutureTask<String> task=new FutureTask<>(new Mycallable());
        new Thread(task).start();
        new Thread(task).start();
        System.out.println(task.get());

    }
}

在这里插入图片描述

4、使用线程池ThreadPoolExecutor

https://blog.51cto.com/u_14234228/2468735

二、说明

2.1 start方法

在前边说过start()方法的作用:
(1)启动线程
(2)调用当前线程的run()方法
那么问题来了:为什么在使用Runnable接口创建线程的方法中,明明是Thread类的对象调用的start(),为什么最终会是实现Runnable接口的类的run()方法被执行,而不是Thread类的run()方法被执行?

(1)首先来看一下Thread类的run()方法的源码:

说明:如果target非空,就执行target的run()方法,那么target又是什么?
(2)再来看一下Thread的一个构造方法Thread(Runnable target)

target是一个Runnable类型的变量,而该变量就是被传进Thread构造器中的参数:

说明:target就是实现了Runnable接口的实现类的实例对象。
因为该对象非空,所以Thread的对象在调用了自身的run()方法,然后发现target对象非空,因此转而执行了实现类的run()方法。

2.2 callable接口和runnable接口的区别

  • 是否有返回值:Runnable无返回值,Callable有返回值
  • 是否抛出异常:call方法计算一个结果,如果不能这样做,就会抛出异常
  • 实现方法名称不同,Runnable接口是run方法,Callable接口是call方法

参考:JUC基础【万字篇】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值