JAVA多线程入门(二):JAVA中如何写多线程

第一种方式:继承Thread

步骤:

1.创建线程类,继承自Thread + 重写run,run中写线程体,线程体就是mian()函数里面的写法

2.使用线程:

2.1 创建线程对象

2.2 线程对象.start()

步骤展示:

1.

public class Rabbit extends Thread {//线程类,继承自Thread
    @Override
    public void run() {//在IDEA中可以通过ctrl+o快捷键快速重写父类函数
        super.run();
        for(int i=0;i<1000;i++){
            System.out.println("兔子跑了"+i+"步");
        }
    }
}

2.

public class RabbitAPP {
    public static void main(String[] args){
        Rabbit rabbit = new Rabbit();//2.1 创建对象
        rabbit.start();//只是加到线程组里面,等待CPU调用。CPU是自动调用的,所以不需要你自己写程序。
    //注意,不要调用run方法。如果你调用run方法,相当于是调用函数而已,没有用到线程方面的内容。
    }
}

第二种方式:通过Runnable接口

为什么有了第一种方式还要使用第二种方式呢?因为Java只支持单继承,如果一个类必须继承自A类,那就无法继承Thread类,所以必须实现接口来实现多线程。

步骤:

1.类实现Runnable接口+重写run()  ------->真实角色类

2.使用线程

2.1 创建真实角色

2.2 创建代理(Thread类)

2.3 代理.start()

这里用到了代理设计模式,你可以先了解一下,基本来说代理设计模式就是:

1.真实类与代理类实现共同接口。

2.代理类中含有真实类引用,并且调用真实类方法。

总结来说就是代理类间接行使真实类的方法。

为什么要这么做呢?你看,哪怕是通过接口,最后还不是要通过Thread类来调用.start()?换句话说,当我们不想或者无法从Thread中继承出类,但是我们还得用Thread类的时候,那我们应该怎么办?

我们应该,想办法将我们写的类和Thread之间构建一个关系。怎么构建关系?把我们写的类当做一个参数传递进去不就好了么。但是问题又来了,我们是把类传递进去了,但是类的写法多样,实现功能也大相径庭,凭什么去保证你的类作为参数传递进Thread的时候,能恰好合适呢?哦,我们可以让他们按照某种规范,或者某种准则。等等,规范?准则?那我懂了,接口!只要让Thread和我们写的类都派生于同一个接口不就好了么?然后在这个接口里写上至少一个必须重写的函数。这样,当我们写的类传递进Thread类的时候,Thread会在内部调用我们的run()函数,而我们无需关系Thrad在内部做了些什么,岂不美哉?

好了,下面给出实例代码:

1.

package com.njust.MyThread;

public class Programmer implements Runnable {
    @Override
    public void run() {
        for(int i=0;i<1000;i++)
            System.out.println("一边敲代码");
}
}

2.

package com.njust.MyThread;

public class ProgrammerApp {
    public static void main(String[] args){
        Programmer programmer = new Programmer();
        Thread proxy = new Thread(programmer);
        proxy.start();
        for(int i=0;i<1000;i++)
            System.out.println("一边聊QQ");
    }
}

 第三种方式:通过Callable接口

好处是可以返回值,也能抛出异常。Callable时Runnable的加强版。

1.创建Callable实现类+重写call

2.借助 执行调度服务 ExecutorService,获取Future对象

ExecutorService ser = Executors.newFixedThreadPool(n);//n代表开启多少个线程

Future result = ser.submit(实现类对象)

3.获取值reslut.get();

4.停止服务ser.shutdownNow();

package com.njust.MyThread;

import java.util.concurrent.*;

public class Call {
    public static void main(String[] args){
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Race racer = new Race();
        Future<Integer> res = executorService.submit(racer);
        int num = 0;
        try {
            num = res.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        executorService.shutdownNow();
        System.out.println(num);

    }
}

class Race implements Callable<Integer> {//这里的泛型是返回值类型

    @Override
    public Integer call() throws Exception {
        return 1000;
    }
}

猜你喜欢

转载自blog.csdn.net/w8253497062015/article/details/82559417
今日推荐