java创建线程的方式

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


    @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方法

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

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

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

5. CompletableFuture

## 1. 继承Thread类,重写run方法

> 先看Thread里的run

    @Override
public void run() {
Runnable task = holder.task;
if (task != null) {
Object bindings = scopedValueBindings();
runWith(bindings, task);
}
}

final Runnable task;

执行的是传进来的Runnable的task

如果没有task当然就不执行啦,所以要重写run方法,因为start的时候会新建一个真正的线程来执行run里的代码

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

 Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("Runnable Thread : "+i);
try {
Thread.sleep(1000);
}catch (Exception e){}
}
}
});
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 使用FutureTask作为Thread的构造器参数,FutureTask其实也是Runnable的子接口

        Thread thread2 = new Thread(futureTask);
thread2.start();
String result = futureTask.get();
System.out.println(result);

而FutureTask构造器里传入Callable对象,线程执行后,可以通过FutureTask的get来获取Callable的执行结果返回值。

        FutureTask<String> futureTask = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println("Callable Thread : "+i);
try {
Thread.sleep(1000);
}catch (Exception e){}
}
return "Callable Thread Done";
}
});

//

### FutureTask

   public V get() throws InterruptedException, ExecutionException{}

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

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

5.

    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);