Java Concurrency: Java threads are three ways to create Java concurrent programming: Java threads created in three ways

Java Concurrency: Java threads created in three ways

table of Contents

introduction

In the daily development work, multi-threaded development can be said to be an essential skill for a good programmer is sure to have a good understanding of this thread, I am a Java programmer, and Java language itself to support the development of a very mature thread , so today we have to the door, to learn about how to create Java threads.

Three ways to create threads

Java to create a thread there are three main ways:

1, inheritance Thread class

2, implement Runnable

3, using the Callable and Future create a thread

These implementations are discussed below three methods, and the contrast between them.

First, the Thread class inheritance

step:

1, create a subclass inherits thread Thread class

2, override run () method, the program needs to run into the thread of execution method, a method where the program will be launched after the thread starts

2, create an instance of the class, and call the object's start () method to start a thread

Sample code is as follows:

public class ThreadDemo extends Thread{
    @Override
    public void run() {
        super.run();
        System.out.println("需要运行的程序。。。。。。。。");
    }

    public static void main(String[] args) {
        Thread thread = new ThreadDemo();
        thread.start();
    }
}

After running the main method, the program will execute the contents of run () method inside, after the execution, the thread along with it die, why must override the run () method do?

Click the source method found Thread's run () method actually have nothing to do

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

public abstract void run();

If the run () There is no need to run the program, then the thread starts directly after the demise. We want to do something you must rewrite the thread run () method. At the same time, it should also be noted that the thread started to call start () method, but directly call run () method can also compile, can be run properly:

public static void main(String[] args) {
    Thread thread = new ThreadDemo();
    thread.run();
}

This is just an ordinary method calls, and not from a new thread, the thread will be lost meaning itself.

Second, implement Runnable

1, define a thread class that implements Runnable interface, the interface and override run () method, the method still comprises a program designated to execute.

2, to create a class instance Runnable, which will be passed as a target parameter, and create a Thread class instance.

3, call the start Thread class instance () method to start a thread.

public class RunnableDemo implements Runnable{
    @Override
    public void run() {
        System.out.println("我是Runnable接口......");
    }
    public static void main(String[] args) {

        RunnableDemo demo = new RunnableDemo();
        Thread thread = new Thread(demo);
        thread.start();
    }
}

This is based on the way the interface, inheritance Thread way than to be a lot of flexibility, but need to create a multi-thread object, open source can be found that when the instance of Runnable class that implements the target passed as a parameter, assigned to the current thread class target, and the program run () is executed in the assignment into the target's run () method.

public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
                      
        ...........这里省略部分源码..........
        
        this.target = target;
        setPriority(priority);
        if (parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }
    
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

Third, the use Callable and Future create a thread

Created using Callable create threads and Runnable interface mode is quite similar thread, the difference is, Callable interface provides a call () method as a thread of execution, and the Runnable interface provides a run () method, at the same time, call () method can have return values, but need to wrap FutureTask Callable object class.

public interface Callable<V> {
    
    V call() throws Exception;
}

step:

1, create a class that implements Callable interface to achieve call () method

2, create a class instance Callable to packaging by FutureTask Callable object class, which encapsulates Call Callable object () Returns the value of the method.

3, FutureTask object will be created as the target argument to create a thread Thread instance and start a new thread.

4, call FutureTask object's get method to get the return value.

public class CallableDemo implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int i = 1;
        return i;
    }

    public static void main(String[] args) {
        CallableDemo demo = new CallableDemo();
        FutureTask<Integer> task = new FutureTask<Integer>(demo);

        new Thread(task).start();
        try {

            System.out.println("task 返回值为:" + task.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

After executing the main method, the program outputs the following results:

task 返回值为:1

Description, task.get () does return a call () method of the result. Then its interior is how to achieve it. The method FutureTask first open configuration, we can see the inside thereof is Callable Callable members object to the current instance as a parameter,

public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;       // ensure visibility of callable
}

Meanwhile, members of the state variable is set to NEW, when the start task, its run method executes the call Callable () 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 {
                //把call()的返回结果复制给result
                result = c.call();
                ran = true;
            } catch (Throwable ex) {
                result = null;
                ran = false;
                setException(ex);
            }
            if (ran)
                //将结果设置给其他变量
                set(result);
        }
    } finally {
        // runner must be non-null until state is settled to
        // prevent concurrent calls to run()
        runner = null;
        // state must be re-read after nulling runner to prevent
        // leaked interrupts
        int s = state;
        if (s >= INTERRUPTING)
            handlePossibleCancellationInterrupt(s);
    }
}
protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            //把传过来的值赋值给outcome成员
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }

After running through a series of procedures, the call () returns the result of the assignment run () method to the outcome, and the outcome is the value when calling task.get () method in the acquisition, this way, will come out ahead the obtained results are returned.

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)
            //返回outcome的值
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }

As can be seen, the operating logic of the source code is quite clear, the code easier to understand, so I am more free to recommend that readers can see more of the underlying Java source code, this will help us further understand how the function is implemented.

Comparison of three methods

Well, three ways to create a thread instance said and done, they went on to say under comparison.

From implementation, the use and Runnable interface Callable interface is basically the same way, the distinction between the method body just achieve Callable can have a return value, and inherit the Thread class is the use of inheritance, it is, in fact, three ways to fall into two categories analysis can be.

1, use the Thread class inheritance:

  • Advantages: coding simple, and when you need to get the current thread, you can directly use this
  • Disadvantages: Since Java supports single inheritance, so you can not inherit other parent after class inheritance Thread

2, and using Runnable interface Callable interfaces manner:

  • Advantage:

More flexible, but the thread that implements the interface can also inherit other parent.

In this way, multiple threads can share a target object is ideal for multi-threaded processing resources with a situation.

Callable interface mode can capture the return value.

  • Disadvantages:

Encode slightly more complicated point, we need to create more objects.

If you want to access the current thread, you need Thread.currentThread () method.

Overall, the two classifications has its own advantages and disadvantages, but in fact the latter's relative advantages and disadvantages's worth noting that, under normal circumstances, it is recommended that interfaces directly with ways to create a thread, after all, a single inherited weaknesses It is quite large.






introduction

In the daily development work, multi-threaded development can be said to be an essential skill for a good programmer is sure to have a good understanding of this thread, I am a Java programmer, and Java language itself to support the development of a very mature thread , so today we have to the door, to learn about how to create Java threads.

Three ways to create threads

Java to create a thread there are three main ways:

1, inheritance Thread class

2, implement Runnable

3, using the Callable and Future create a thread

These implementations are discussed below three methods, and the contrast between them.

First, the Thread class inheritance

step:

1, create a subclass inherits thread Thread class

2, override run () method, the program needs to run into the thread of execution method, a method where the program will be launched after the thread starts

2, create an instance of the class, and call the object's start () method to start a thread

Sample code is as follows:

public class ThreadDemo extends Thread{
    @Override
    public void run() {
        super.run();
        System.out.println("需要运行的程序。。。。。。。。");
    }

    public static void main(String[] args) {
        Thread thread = new ThreadDemo();
        thread.start();
    }
}

After running the main method, the program will execute the contents of run () method inside, after the execution, the thread along with it die, why must override the run () method do?

Click the source method found Thread's run () method actually have nothing to do

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

public abstract void run();

If the run () There is no need to run the program, then the thread starts directly after the demise. We want to do something you must rewrite the thread run () method. At the same time, it should also be noted that the thread started to call start () method, but directly call run () method can also compile, can be run properly:

public static void main(String[] args) {
    Thread thread = new ThreadDemo();
    thread.run();
}

This is just an ordinary method calls, and not from a new thread, the thread will be lost meaning itself.

Second, implement Runnable

1, define a thread class that implements Runnable interface, the interface and override run () method, the method still comprises a program designated to execute.

2, to create a class instance Runnable, which will be passed as a target parameter, and create a Thread class instance.

3, call the start Thread class instance () method to start a thread.

public class RunnableDemo implements Runnable{
    @Override
    public void run() {
        System.out.println("我是Runnable接口......");
    }
    public static void main(String[] args) {

        RunnableDemo demo = new RunnableDemo();
        Thread thread = new Thread(demo);
        thread.start();
    }
}

This is based on the way the interface, inheritance Thread way than to be a lot of flexibility, but need to create a multi-thread object, open source can be found that when the instance of Runnable class that implements the target passed as a parameter, assigned to the current thread class target, and the program run () is executed in the assignment into the target's run () method.

public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
                      
        ...........这里省略部分源码..........
        
        this.target = target;
        setPriority(priority);
        if (parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }
    
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

Third, the use Callable and Future create a thread

Created using Callable create threads and Runnable interface mode is quite similar thread, the difference is, Callable interface provides a call () method as a thread of execution, and the Runnable interface provides a run () method, at the same time, call () method can have return values, but need to wrap FutureTask Callable object class.

public interface Callable<V> {
    
    V call() throws Exception;
}

step:

1, create a class that implements Callable interface to achieve call () method

2, create a class instance Callable to packaging by FutureTask Callable object class, which encapsulates Call Callable object () Returns the value of the method.

3, FutureTask object will be created as the target argument to create a thread Thread instance and start a new thread.

4, call FutureTask object's get method to get the return value.

public class CallableDemo implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int i = 1;
        return i;
    }

    public static void main(String[] args) {
        CallableDemo demo = new CallableDemo();
        FutureTask<Integer> task = new FutureTask<Integer>(demo);

        new Thread(task).start();
        try {

            System.out.println("task 返回值为:" + task.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

After executing the main method, the program outputs the following results:

task 返回值为:1

Description, task.get () does return a call () method of the result. Then its interior is how to achieve it. The method FutureTask first open configuration, we can see the inside thereof is Callable Callable members object to the current instance as a parameter,

public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;       // ensure visibility of callable
}

Meanwhile, members of the state variable is set to NEW, when the start task, its run method executes the call Callable () 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 {
                //把call()的返回结果复制给result
                result = c.call();
                ran = true;
            } catch (Throwable ex) {
                result = null;
                ran = false;
                setException(ex);
            }
            if (ran)
                //将结果设置给其他变量
                set(result);
        }
    } finally {
        // runner must be non-null until state is settled to
        // prevent concurrent calls to run()
        runner = null;
        // state must be re-read after nulling runner to prevent
        // leaked interrupts
        int s = state;
        if (s >= INTERRUPTING)
            handlePossibleCancellationInterrupt(s);
    }
}
protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            //把传过来的值赋值给outcome成员
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }

After running through a series of procedures, the call () returns the result of the assignment run () method to the outcome, and the outcome is the value when calling task.get () method in the acquisition, this way, will come out ahead the obtained results are returned.

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)
            //返回outcome的值
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }

As can be seen, the operating logic of the source code is quite clear, the code easier to understand, so I am more free to recommend that readers can see more of the underlying Java source code, this will help us further understand how the function is implemented.

Comparison of three methods

Well, three ways to create a thread instance said and done, they went on to say under comparison.

From implementation, the use and Runnable interface Callable interface is basically the same way, the distinction between the method body just achieve Callable can have a return value, and inherit the Thread class is the use of inheritance, it is, in fact, three ways to fall into two categories analysis can be.

1, use the Thread class inheritance:

  • Advantages: coding simple, and when you need to get the current thread, you can directly use this
  • Disadvantages: Since Java supports single inheritance, so you can not inherit other parent after class inheritance Thread

2, and using Runnable interface Callable interfaces manner:

  • Advantage:

More flexible, but the thread that implements the interface can also inherit other parent.

In this way, multiple threads can share a target object is ideal for multi-threaded processing resources with a situation.

Callable interface mode can capture the return value.

  • Disadvantages:

Guess you like

Origin www.cnblogs.com/xues/p/11810122.html