Java语法基础——线程

线程的创建


什么是线程

线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。——百度百科

就像团队与个人的关系。团队接到一个任务,会把任务发放下去,实际的执行是由一个人来完成的,每个人可以进行不同的工作。

线程的实现

在Java中实现线程有三种方式。第一种方式是继承Thread类,第二种方式是实现Runnable接口。第三种方式是实现Callable接口。不管哪种方式,最后的目标都是为了实例化Thread类。

继承Thread类实现线程,代码如下:

//继承Thread类
public class MyThread extends Thread{
    int sum=0;
    //创建子线程的有参构造方法
    public MyThread(String name){
        super(name);
    }
    //重写run()方法
    @Override
    public void run() {
        while(sum++<10) {
            System.out.println(getName() + "-------" + sum);
        }
    }
}
//main函数
public static void main(String[] args) {
    //创建线程对象
    //MyThread thread1=new MyThread();
    //thread1.setName("thread1");
    //这里直接传入了线程名称 效果和上面代码一样
    MyThread thread1=new MyThread("thread1");
    MyThread thread2=new MyThread("thread2");
    //启动线程
    thread1.start();
    thread2.start();
}

实现Runnable接口实现线程,代码如下:

//实现Runnable接口
public class MyRunnable implements Runnable {
    int sum=0;
    //重写run()方法
    @Override
    public void run() {
        while(sum++<10){
            System.out.println(Thread.currentThread().getName()+"------"+sum);
        }
    }
}
//main函数
public static void main(String[] args) {
    //创建Runnable接口的实现类对象
    MyRunnable myRunnable=new MyRunnable();
    //创建Thread对象
    Thread thread1=new Thread(myRunnable,"Thread1");
    Thread thread2=new Thread(myRunnable,"Thread2");
    //启动线程
    thread1.start();
    thread2.start();
}

实现Callable接口实现线程,代码如下:

//实现Callable接口
public class MyCallable implements Callable {
    int num=0;
    //重写call()方法 注意返回值类型不是void
    @Override
    public Object call() throws Exception {
        while(num++<10){
            System.out.println(Thread.currentThread().getName()+"------"+num);
        }
        return num;
    }
}
//main函数
public static void main(String[] args) throws ExecutionException, InterruptedException {
     //创建Callable接口实现类对象
     MyCallable myCallable=new MyCallable();
     //使用FutureTask封装Callable接口
     FutureTask<Object> ft1=new FutureTask<Object>(myCallable);
     //创建线程对象
     Thread thread1=new Thread(ft1,"Thread_1");
     FutureTask<Object> ft2=new FutureTask<Object>(myCallable);
     Thread thread2=new Thread(ft2,"Thread_2");
     //启动线程
     thread1.start();
     thread2.start();
     //使用FutureTask对象的get()方法获取返回值
     System.out.println(ft1.get());
     System.out.println(ft2.get());
 }

上面的实现代码中我们可以发现

(1)继承Thread类方式的一般使用过程

  • 新建一个类MyThread(类名可以随便起)继承Thread类
  • 重写Thread类的run()方法,run()方法里面的内容就是我们启动线程时执行的内容
  • 构造MyThread对象
  • 使用线程对象

(2)实现Runnable接口方式的一般使用过程

  • 新建一个类MyRunnable(类名可以随便起)实现Runnable接口
  • 重写Thread类的run()方法,run()方法里面的内容就是我们启动线程时执行的内容
  • 构造MyRunnable对象,然后利用Thread类构造方法Thread(Runnable target)创建线程对象
  • 使用线程对象线程

(3)实现Callable接口的一般使用过程

  • 新建一个类继承(类名可以随便起)实现Callable接口
  • 重写Callable的call()方法
  • 创建Callable实现类对象 用FutureTask类封装Callable实现类对象
  • 使用Thread对象的Thread(Runnable target)构造方法创建线程对象
  • 使用线程对象

Notes:
① Runnable接口和Callable接口的使用基本上没有区别。最大的区别就在于Callable接口call()方法的返回值类型是Object,而Runnable接口的run()方法返回值是void

② Runnable和Callable接口并不是Thread类,要想Runnable接口和Callable接口像Thread类一样使用,必须通过一定操作将实现Runnable接口的类或者实现Callable接口的类转为Thread类。我认为,这是实现接口和继承类方式实现线程的最大不同。

  • 在run()方法体内,想要使用Thread的方法(以获取线程名称为例)。如果继承Thread类的方式,只需要 getName() 就好;而如果实现Runnable接口或者Callable接口的方式,就需要利用Thread类的静态方法currentThread() 返回当前线程对象,如:Thread.currentThread().getName()
  • 在Thread对象实例化过程中,继承Thread类的方式直接实例化自己的MyThread类就好,如:MyThread thread=new MyThread(); 而实现Runnable接口方式在实例化自己的MyRunnable类之后还需要通过Thread类的构造方法转为Thread对象,如:MyRunnable runnable=new MyRunnable();Thread thread=new Thread(runnable); Callable类参考上面代码。

③ 因为实现接口的方式实现线程,都需要对接口的实现类进行进一步转化,最终创建Thread对象。我们可以在创建Thread对象时传入相同的接口实现类,这样就会实现线程资源的共享。

④ 一个类只能继承一个类,但可以实现多个接口。因此,在需要使用线程的地方,最好使用实现接口的方式。

⑤ Thread类有三个静态成员返回线程的优先级。分别是static int MAX_PRIORITY ——返回线程可以拥有最大优先级,static int MIN_PRIORITY ——返回线程可以拥有最小优先级, static int NORM_PRIORITY ——返回线程默认分配优先级 。线程的优先级一般在1~10之间。这个具体想要了解可以点击下方链接:

⑥ 运行上面第二段代码和第三段代码的话,会发现运行的结果毫无顺序可言,总感觉代码出了问题。前面③中提到过,线程之间会共享资源,而线程访问资源是随机的,一个线程在对资源进行操作未完成时,另一个线程可能也在对线程进行操作,就会出现我们看到的混乱的运行结果。详细的解决办法可以点击下方链接:

链接会尽快更新,请耐心等待。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值