Java: multithreading overview and creation method

Java: multithreading overview and creation method

In the previous learning process, concurrency, thread and synchronous and asynchronous content have been mentioned more than once. However, due to the local integration of the content, several strokes have been taken before, and attached: I will talk about it in detail in the future.

Well, now it's time to elaborate. After reading and referring to the book on Java Concurrent Programming, I suddenly feel a little pressure, because some concepts are really abstract. So the length of the content is uncertain, but I will try to output some every day.

Processes and threads

A process can have multiple threads, and a thread must have a parent process. Process: the task currently being executed by the operating system is also an execution process of the operating system running program. Thread: it is the execution unit of the process and the sub task being executed in the process. Just like the QQ we are using, the music software we are playing songs, and the games we are playing are processes one by one. The various operations we perform in the QQ process are threads.

Concurrency and parallelism

Most operating systems now support multi process concurrent operation. Just as we are using the computer now, you can check through the task manager and find that dozens or hundreds of processes are "executing at the same time" Simultaneous execution "is quoted, obviously not in fact.

Concurrency: take processes for example. At the same time, only one instruction can be executed, but multiple processes can be executed in turn quickly. The speed of CPU execution makes people execute these processes at the same time. Parallelism: multiple process instructions are executed simultaneously on multiple processors at the same time.

Just look at the following figure:

Next is my hypothetical scenario of concurrency and parallelism: concurrency scenario: suppose there is a computer that can only be played by one person. The eldest brother and the second brother want to play for a while. There is no way. We have to find a way to solve it. Let's have a fight. Whoever gets it counts. No matter who grabs it, they will not stop until they are satisfied. This is the efficient preemptive multitasking operation strategy adopted by the current operating system. Parallel scene: now there are two computers. The eldest and the second play their own computers, neither competing nor robbing.

Advantages of multithreading

Threads are called lightweight processes. In most cases, the execution of multi threads in the process is preemptive, just like the concurrent multi processes of the operating system.

Advantages of multithreading over multiprocessing:

The following references are from Java Concurrent Programming Practice:

Thread creation and startup

Let's take a look at this key class in multithreaded programming, Java Lang. thread, the official document says: there are two ways to create a thread, which are as follows:

Inherit thread class

Create a thread as follows:

/*创建线程*/
//创建一个类继承Thread类
class TDemo extends Thread{
    //线程要执行的任务在run方法中
    @Override
    public void run(){
        for (int i = 0; i < 5; i++) {
            System.out.println(i);
        }
    }
}

The startup thread is as follows:

    public static void main(String[] args){
        //创建了TDemo的实例
        TDemo t1 = new TDemo();
        //启动线程,并调用run方法
        t1.start();
        System.out.print("main");
    }
    //输出结果:main01234

Creating an instance object of tdemo does not start the thread corresponding to the instance. To start, you need to call the start () method of the thread object.

Start() and run()

Let's try to replace the start () method with the run () method and see the result: 01234main

We can see from the output results that when we call the start () method, the system will treat the run () method as a thread executor, and the main thread and the thread we created will execute concurrently. However, if you simply call the run () method, the system will treat the thread object as an ordinary object, and the run () method is only a part of the ordinary object method and a part of the main thread.

Implement runnable interface

***

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}
//实现Runnable接口
class RDemo implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(i);
        }
    }
}

//创建并启动线程
Thread t = new Thread(new RDemo());
t.start();

Call the public thread (runnable target) constructor and pass in the runnble interface type object as a parameter to build the thread object. Of course, it can also be in the form of anonymous inner classes:

    //匿名内部类创建并启动线程
    new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.print(i);
            }
        }
    }).start();

Implement callable interface

This is the content of the callable interface:

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

In addition to the above two methods, we can see from the book that there is a new method in Java 5, which uses the callable interface. The official document describes it as follows:

The callable interface alone is not enough. After all, it came out after five years. In order to avoid modifying the previous code and adapt to the current environment, java5 also added a supporting future interface:

public interface Future<V> {

    //试图取消Callable中任务的执行,如果任务已经完成、已经被取消、或因其他原因无法被取消,返回false。
    boolean cancel(boolean mayInterruptIfRunning);

    //如果此任务在正常完成之前被取消,则返回true
    boolean isCancelled();

    //如果此任务已完成(正常的终止、异常或取消),则返回true
    boolean isDone();

    //如果需要,则等待计算完成,然后检索其结果。
    V get() throws InterruptedException,ExecutionException;
    
    //如果需要,将等待最多给定的时间以完成计算,然后检索其结果。
    V get(long timeout,TimeUnit unit)
        throws InterruptedException,ExecutionException,TimeoutException;
}

Through the inheritance relationship, it can be found that the runnablefuture interface inherits both the runnablefuture interface and the future interface, which means that the class implementing the runnablefuture interface is both the implementation class of runnable and the implementation class of future. Futuretask plays such a role. Its instance can be passed into the constructor of thread as target.

By looking at the source code, you can find that futuretask internally maintains a callable object. You can initialize the callable object through the following constructor.

    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
    FutureTask<Integer> task = new FutureTask<>(new Callable<Integer>() {
        @Override
        public Integer call() throws Exception {
            int i = 0;
            while(i<10){
                System.out.println(Thread.currentThread().getName());
                i++;
            }
            return i;
        }
    });

new Thread(task,"name").start();

    try {
        System.out.println(task.get());
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }

Differences in creation methods

What is the difference between inheriting class thread and implementing interface (runnable or callable)?

//继承Thread
System.out.print(this.getName()+i);
//实现Runnable接口
System.out.print(Thread.currentThread().getName()+i);

As a personal learning note, this paper still stays at a relatively simple level, and needs a lot of practice to understand the profound meaning of concurrent programming.

References: Java Concurrent Programming practice, crazy Java handout, Java multithreading design pattern

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>