Java多线程——实现线程的方式以及线程的状态

什么是线程
线程是进程中独立运行的子任务(进程是受操作系统管理的基本运行单元),在没有同步的情况下,线程的执行是随机乱序的。
在Java编程中,有四种方式去实现多线程。

一、实现Runnable接口

Runnable接口中只有一个抽象run()方法,这个方法是运行线程的入口,而不是启动线程的入口,启动线程用start()方法,实现这个接口的类就具有了多线程的功能了。

public class MyThread implements Runnable {

    private String name;
    public MyThread(String name) {
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println("inner thread is running!");
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

实现Runnable接口的类,需要使用Thread类的构造函数实例化一个线程,下面使用了带有线程名称的构造函数,第二个参数是线程名称。

public Thread(Runnable target, String name)

运行测试:

    public static void main(String[] args) {
    Thread thread = new Thread(new MyThread("mythread"),"mythread");
        thread.start();
        System.out.println(thread.getName());
        System.out.println("main thread is running!" +Thread.currentThread().getName());
    }

运行结果:

mythread
inner thread is running!
main thread is running!main
二、继承Thread类

其实继承Thread类实现多线程,本质上也是实现了Runnable接口,因为Thread类实现了Runnable接口。

public class MyThread extends Thread {
    private String some;
    public MyThread(String some) {
        this.some = some;
    }
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" is running!"+"--"+getSome());
    }
    public String getSome() {
        return some;
    }
    public void setSome(String some) {
        this.some = some;
    }
}

实现Thread类,在实例化一个线程时,只需要实例化该类。

    public static void main(String[] args) {
        MyThread thread = new MyThread("mythread");
        thread.start();
    System.out.println(Thread.currentThread().getName()+" thread is running!" );
    }

运行结果:

main thread is running!
Thread-0 is running!--mythread
三、继承TimerTask类

由于TimerTask实现了Runnable接口,因此继承TimerTask也能够实现多线程。用这种方法,有两种方式启动线程。

  1. 使用定时器Timer的调度方法schedule()。
  2. 使用Thread的构造函数。
    private static Timer timer = new Timer();

        public static class Mytask extends TimerTask{
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" is running!");
            }
        }
        public static void main(String[] args) {
            //第一种启动方法
            Mytask mytask = new Mytask();
            timer.schedule(mytask, 1000L);
            //第二种启动方法
            Thread thread = new Thread(mytask,"mytask");
            thread.start();
        }

运行结果:

mytask is running!
Timer-0 is running!
四、实现Callable接口

Callable接口中只有一个call()方法,该方法具有返回值,并且可以抛出异常。和Runnable接口有很大的区别,是一种更加高级的实现。

public class CallableService<T> implements Callable<T> {
    private int age;
    public CallableService(int age) {
        super();
        this.age=age;
    }
    @Override
    public T call() throws Exception {
        System.out.println(Thread.currentThread().getName()+" is running!");
        return  (T) ("返回值是:"+age);
    }
}

启动该线程,只需要实例化实现Callable接口的类,然后调用call()方法。
运行测试:

    public static void main(String[] args) throws Exception {
        CallableService<String> service = new CallableService<String>(100);
        String t = service.call();
    }

测试结果:

返回值是:100

Callable可以结合Future使用,能够实现更多的功能。这个在后续的博客中会讲到。

线程的状态

  1. 初始化状态:即线程的新生状态,使用new出来的线程。
  2. 运行状态:在线程调用start()方法后,且没有发生任何意外和认为的中断,此时线程处于运行状态。
  3. 阻塞状态:线程调用wait(),sleep(),suepend()方法后,将处于该状态。
  4. 销毁状态:线程自然的运行结束或调用stop()方法销毁线程。

    这里写图片描述

这个图不是最完善的,在暂停状态时,当有线程调用notify()或notifyAll()方法时,阻塞的线程会抢占监视器,先得到监视器的线程先执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值