[Concurrent Programming] Three ways to create threads

source code

Runnable

functional interface

package java.lang;  
@FunctionalInterface  
public interface Runnable {
    
      
public abstract void run();  
}

Thread

It is a typical static proxy mode

public   class Thread implements Runnable {
    
    
	private Runnable target;
	public Thread() {
    
      
	    init(null, null, "Thread-" + nextThreadNum(), 0);  
    }  
    public Thread(Runnable target) {
    
      
	    init(null, target, "Thread-" + nextThreadNum(), 0);  
	}
	@Override  
	public void run() {
    
      
	    if (target != null) {
    
      
	        target.run();  
	    }  
	}
}

FutureTask

The run() of FutureTask actually calls the call() method of Callable, and the returned realut can be obtained through the get() method

public void run() {
    
      
    if (state != NEW ||  
        !UNSAFE.compareAndSwapObject(this, runnerOffset,  
                                     null, Thread.currentThread()))  
        return;  
    try {
    
      
        Callable<V> c = callable;  
        if (c != null && state == NEW) {
    
      
            V result;  
            boolean ran;  
            try {
    
      
                result = c.call();  
                ran = true;  
            } catch (Throwable ex) {
    
      
                result = null;  
                ran = false;  
                setException(ex);  
            }  
            if (ran)  
                set(result);  
        }  
    } finally {
    
       
        if (s >= INTERRUPTING)  
            handlePossibleCancellationInterrupt(s);  
    }  
}
protected void set(V v) {
    
      
    if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
    
      
        outcome = v;  
        UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state  
        finishCompletion();  
    }  
}






public V get() throws InterruptedException, ExecutionException {
    
      
    int s = state;  
    if (s <= COMPLETING)  
        s = awaitDone(false, 0L);  
    return report(s);  
}
private V report(int s) throws ExecutionException {
    
      
    Object x = outcome;  
    if (s == NORMAL)  
        return (V)x;  
    if (s >= CANCELLED)  
        throw new CancellationException();  
    throw new ExecutionException((Throwable)x);  
}

Class Diagram

image.png

1. Inherit Thread

Inherit Thread, rewrite the run method

    @Test  
    public void test2(){
    
      
        // 创建线程对象  
        Thread t = new subThread();  
        // 启动线程  
        t.start();  
    }  

class subThread extends Thread{
    
      
    @Override  
    public void run() {
    
      
        System.out.println("任务1");  
    }  
}

or

anonymous subclass

@Test  
public void test1(){
    
      
    // 创建线程对象  
    Thread t = new Thread() {
    
      
        @Override  
        public void run() {
    
      
            System.out.println("任务1.1");  
        }  
    };  
    // 启动线程  
    t.start();  
}

2. Pass the Runnable object to the Thred object (recommended)

    @Test  
    public void test3(){
    
      
        Runnable runnable = new RunnableImpl();  
        Thread thread = new Thread(runnable);  
        thread.start();  
    }  

class RunnableImpl implements  Runnable{
    
      
    @Override  
    public void run() {
    
      
        System.out.println("任务2");  
    }  
}

The recommended writing method is to use lamada expressions to generate Runable anonymous inner class objects, and then pass them to Thred objects.
Separate tasks and threads for more flexibility

@Test  
public void test4(){
    
      
    Runnable runnable = () -> System.out.println("任务2.2");  
    Thread thread = new Thread(runnable);  
    thread.start();  
}

Principle
Thread's run method uses the static proxy mode, and the run that executes the thred object actually executes the run method of the anonymous Runnable implementation class object.

@Override  
public void run() {
    
      
    if (target != null) {
    
      
        target.run();  
    }  
}

3. Pass the FutureTask object to the Thread object

@Test  
public void test5() throws ExecutionException, InterruptedException {
    
      
    // 创建任务对象  
    FutureTask<Integer> task3 = new FutureTask<>(() -> {
    
      
        System.out.println("任务3");  
        return 100;  
    });  
    // 参数1 是任务对象; 参数2 是线程名字,推荐  
    new Thread(task3, "t3").start();  
    // 主线程阻塞,同步等待 task 执行完毕的结果  
    Integer result = task3.get();  
    System.out.println(result);  
  
}

Guess you like

Origin blog.csdn.net/weixin_50799082/article/details/131270925