java创建线程的方式


# 首先看java是怎么执行多线程的

//默认执行Thread对象的run方法。虽然没有显式调用。

    @Override
    public void run() {
        Runnable task = holder.task;
        if (task != null) {
            Object bindings = scopedValueBindings();
            runWith(bindings, task);
        }
    }
    public void start() {
        synchronized (this) {
            // zero status corresponds to state "NEW".
            if (holder.threadStatus != 0)
                throw new IllegalThreadStateException();
            start0();
        }
    }
    private native void start0();


> 可以看到,真正创建线程的代码是native的。这里其实就是执行当前Thread的run方法里的内容。

>> 当没有重写run时就得有一个Runnable的任务



# java创建线程的方式

1. 继承Thread类,重写run方法。因为线程会默认执行Thread对象的run方法。

public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程执行:" + Thread.currentThread().getName());
    }
}

// 使用
MyThread thread = new MyThread();
thread.start();

2. 使用Runnable作为Thread的构造器参数

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程执行:" + Thread.currentThread().getName());
    }
}

// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();

或者lamda:
Thread thread = new Thread(() -> {
    for (int i = 0; i < 1000; i++) {
        System.out.println("Runnable Thread : "+i);
        try {
            Thread.sleep(1000);
        }catch (Exception e){}
    }
});

3. 使用FutureTask+Callable 作为Thread的构造器参数,FutureTask其实也是Runnable的子接口

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

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

// 使用
Callable<String> task = new MyCallable();
FutureTask<String> futureTask = new FutureTask<>(task);
Thread thread = new Thread(futureTask);
thread.start();

// 获取返回值(阻塞等待)
String result = futureTask.get(); // "Hello from Thread-0"

4. 使用线程池 但是这个的意思其实不是创建新线程了,而是使用将任务提交到线程来执行。ExecutorService的submit会返回Future。

5. CompletableFuture

    CompletableFuture<String> future = CompletableFuture.supplyAsync(()->{
        System.out.println("in future");
        return "future end";
    });
    System.out.println("in main");
    String s = future.get();
    System.out.println(s);

//

### FutureTask

   public V get() throws InterruptedException, ExecutionException{}

   public V get(long timeout, TimeUnit unit){}

阻塞, 可以设置超时时间。其实超过时间了线程还是在运行,只不过读取的这个事件不再阻塞了。