JAVA多线程(一)--实现/创建方式

JAVA多线程(一)--实现/创建方式

一、继承Thread类

Thread类本质上是一个实现了Runnable接口的实例,代表一个线程的实例。启动线程的唯一方法是调用Thread类的start()方法,start()方法中调用了一个native方法start0(),它将启动一个线程,并执行run()方法。

//部分Thread源码
public class Thread implements Runnable {
    //......
    public synchronized void start() {

        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    // 本地方法,使用c代码初始化线程,并运行run()方法
    private native void start0();

    @Override
    public void run() {
        if (target != null) {
            //这里的target是一个Runnable接口实现的引用
            target.run();
        }
    }
    // .....
}

代码:

// 继承Thread类
public class MyThread extends Thread{
    @Override
    public void run(){
        System.out.println("MyThread running");
    }

    public static void main(String[] arg){
	//创建线程并运行
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

二、实现Runnable接口

如果类已经继承了一个类,就无法再继承Thread类,此时可以实现一个Runnable接口。

// Runnable源码
@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

使用Runnable接口实现线程类时,为了启动线程,需要用该类初始化一个Thread类对象。

// 实现代码
public class MyThread1 extends MyThread implements Runnable{
    @Override
    public void run(){
        System.out.println("MyThread1 running");
    }

    public static void main(String[] arg){
        MyThread1 myThread1 = new MyThread1();
        Thread thread = new Thread(myThread1);
        thread.start();
    }
}

三、实现Callable接口

无返回值的任务实现Runnable接口,而有返回值的任务就需要实现Callable接口。
执行Callable任务后,返回一个Future对象。在该对象上调用get()方法就可以得到Callable任务返回的对象。使用Callable需要结合ExecutorService线程池接口。

// Callable源码
@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}
// 实现代码:
public class MyCallableThread implements Callable<String> {

    private final String name;
    MyCallableThread(String name){
        this.name = name;
    }
    @Override
    public String call(){
        return this.name;
    }

    public static void main(String[] arg) throws ExecutionException, InterruptedException {
        int size = 5;
        ExecutorService pool = Executors.newFixedThreadPool(size);
        List<Future<String>> futures = new ArrayList<>();
        for(int i=0;i<size;i++){
            Future<String> future = pool.submit(new MyCallableThread(i+""));
            futures.add(future);
        }
        pool.shutdown();
        for (Future<String> future : futures){
            System.out.println("res: "+ future.get());
        }
    }
}
   /**
     * 执行结果:
     * res: 0
     * res: 1
     * res: 2
     * res: 3
     * res: 4
     */

四、基于线程池

每次创建线程都要为线程分配堆栈内存以及初始化内存,还需要进行系统调用。频繁的创建和销毁线程会大大降低系统运行效率,非常浪费资源。可以使用缓存的策略,也就是线程池来实现多线程。
详情:JAVA多线程(二)--线程池

posted @   残忍的幻象饭团  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示