Java 中创建线程的方式

版权声明:作者:N3verL4nd 出处: https://blog.csdn.net/lgh1992314/article/details/79778575

继承 Thread 类

定义 Thread 类的子类,并重写该类的run()方法,该run()方法的方法体就代表了该线程要完成的任务。因此把run()方法称为执行体。本质上讲,run() 就是我们自定义的回调函数,既然是回调函数,我们直接调用它就没有任何意义了~
然后创建 Thread 子类的实例,即创建了线程对象。调用线程对象的start()方法来启动该线程。

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " starts...");
    }
}
public class Main {
    public static void main(String[] args) {
        Thread thread = new MyThread();
        thread.start();
    }
}

Thread.currentThread()方法返回当前正在执行该方法执行的线程对象。
getName() 方法返回该线程的名称

实现 Runnable 接口

定义java.lang.Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

package java.lang;
@FunctionalInterface // 支持函数式调用
public interface Runnable {
    public abstract void run();
}
// 作为线程的任务而存在
class MyRunnable implements java.lang.Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " starts...");
    }
}
public class Main {
    public static void main(String[] args) {
        new Thread(new MyRunnable(), "first thread").start();
        new Thread(new MyRunnable(), "second thread").start();
    }
}

我们来看看它是如何实现的:

//
private Runnable target;
public Thread(Runnable target, String name) {
    init(null, target, name, 0);
}
@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

匿名内部类的方式

public class Main {
    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " starts...");
            }
        }.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " starts...");
            }
        }).start();
    }
}

对于以下代码,输出结果是什么呢?

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

输出结果为Thread::run
因为我们已经覆盖了Thread.run()方法(子类覆盖父类的方法)–> 多态。

通过 Callable 和 Future 创建线程

  • 创建 Callable 接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
  • 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的call()方法的返回值。
  • 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
  • 调用 FutureTask 对象的get()方法来获得子线程执行结束后的返回值
package test;

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

class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println(Thread.currentThread().getName() + " starts...");
        return "Hello World";
    }
}

public class Main {
    public static void main(String[] args) {
        FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
        Thread thread = new Thread(futureTask);
        thread.start();

        try {
            // 获取线程返回值
            String val = futureTask.get();
            System.out.println("返回值: " + val);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

定时器实现

import java.util.Timer;
import java.util.TimerTask;

public class Main {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hi");
            }
        }, 0, 1000);
    }
}

更强大的控制可以使用 quartz

使用线程池

package test;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) {
        Executor executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                    try {
                        TimeUnit.MILLISECONDS.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        ((ExecutorService) executor).shutdown();
    }
}

参考:

https://blog.csdn.net/longshengguoji/article/details/41126119

猜你喜欢

转载自blog.csdn.net/lgh1992314/article/details/79778575