Java Concurrency (a) --- Multi-Thread Starter

Java Concurrency (a) --- Multi-Thread Starter

1, the basic concept

1.1, processes and threads

  • Process: is a program, the system is running a program that is a process from creation to the demise of the process.
  • Thread: A process can produce during the execution of multiple threads, such as running 360 software is a person process running, if 360 again rubbish, again antivirus, the equivalent of multiple threads to perform different tasks (only to facilitate Let's understand this fight).
  • Multithreading: a plurality of threads are alternately performed, if a plurality of threads will be executed sequentially mononuclear CPU, multi-core CPU, then CPU will be performed simultaneously in a plurality according to each CPU of its own operator.

1.2, synchronous and asynchronous

  • Sync: method call once started must wait until after the method call returns, in order to continue with the subsequent behavior

  • Asynchronous: method calls start method call will return immediately, the caller can continue to operate immediately behind, do not wait until the method returns.

    About more classic and common asynchronous implementation of the message queue is: when not in use the message queue, requesting the user data is written to the database directly, in the case of high concurrent database pressure surge will cause the response speed becomes slower. After using message queues, the user returns the requested data immediately after sending the message queue, and then written to the database to obtain data from the asynchronous message queue by a consumer process message queues. Since message queue database server processing speed (message queue has better scalability than the database), thus a significant improvement in the speed of the effect.

1.3, concurrency and parallelism

  • Concurrency: support for simultaneous multi-tasking processing power, but multitasking is not necessarily performed simultaneously.

  • Parallel: representation can perform multiple tasks simultaneously.

    For example, you eat at the same time suddenly came a phone call, you eat half a meal put down the chopsticks to pick up the phone to answer the phone, continue to eat the rest of the meal after you answer the phone, which is concurrent, can handle multiple tasks simultaneously, but can only be executed at the same time a, or answer the phone, or eat, if you can answer the phone while eating side, then this is a parallel.

1.4, high concurrency

High concurrency problem is Internet distributed system architecture design must be considered, generally refers to the system can handle a lot of requests in parallel.

General indicators include: response time, throughput, queries per second rate QPS, the number of concurrent users.

1.5, blocking and non-blocking

  • Blocked: you can not get results before blocking the current thread.
  • Non-blocking: the obstruction opposite.

1.6, the critical region

Generally used to represent the shared area can be used simultaneously by multiple threads, but each time only one thread can use it, once the critical section is occupied, other threads must wait.

2. Create the way threads

2.1, inheritance Thread class

public class MyThread extends Thread {
    @Override
    public void run() {
        super.run();
        System.out.println("MyThread");
    }

        //测试
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();
        System.out.println("end");
    }
}

operation result:

end
MyThread

2.2 anonymous inner classes

    public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                super.run();
                System.out.println("thread_01");
            }
        };
        t.start();
        System.out.println("end");
    }

operation result:

end
thread_01

2.3, implement Runnable

public class MyThread implements Runnable {

    @Override
    public void run() {
        System.out.println("thread");
    }

    public static void main(String[] args) {
        Thread t = new Thread(new MyThread());
        t.start();
        System.out.println("end");
    }

}

Results of the:

end
thread

2.4 thread pool

One way to use the thread pool is the most recommended, will elaborate later

3, thread life cycle

3.1, New (New)

When a thread is created using the new keyword, the thread for the new state.

3.2, Runnable (ready)

After calling start () method, but not assigned to the CPU, waiting for the system to assign CPU, when the system waits for a thread of execution is selected, he will become operational status from the ready state, this is called the CPU scheduler.

3.3, Running (running)

Execute the code inside when the run method.

3.4, Blocked (blocking)

In this case can not be assigned to the CPU, the synchronized code block or a modified method can be a uniform thread of execution time, compete for the thread becomes the lock Runnable state, while competing thread becomes the lock state from Runnable to Blocked state. And the contract will lock the thread in a wait state instead of blocking, blocking only synchronized

3.5, Waiting (unlimited wait)

Also when this situation can not be assigned to the CPU, there are three cases will thread into the Waiting state Runnable state.

  1. Call the no-argument Object.wait () method, until the notify () or notifyAll () will return Runnable state wake.
  2. Call the no-argument Thread.join () method. A call B.join in thread () method, the thread will wait until A B thread execution will be implemented over, this time in a wait state Ac.
  3. Call LockSupport.park () method. LockSupport is a utility class Java6 introduced, Java and lock in the contract are based on his realization, then call LockSupport.unpark (Thread thread) method will allow the thread is Runnable state.

3.6, Time_Waiting (limited time to wait)

  1. Object.wait(long timeout);
  2. Thread.join(long millis);
  3. Thread.sleep(long millis)
  4. LockSupport.parkNanos(Object blocked,long deadline)
  5. LockSupport.parkUntil(long deadline)

3.7, Dead (termination)

At the end of our run thread execution method, or perform an exception it is thrown half into the final state.

3.7.1 How to forcibly terminate the thread

Thread.stop () method has been abandoned, is not recommended, because if you get a lock this thread, this time is stop, this lock is not, then the other threads will not get the lock.

/**
 * 使用interrupt来停止线程
 */
public class MyThread06 extends Thread {
    @Override
    public void run() {
        for(int i = 0 ; i < 100000 ; i ++){
            if(this.isInterrupted()){
                System.out.println("end");
                return;
            }
            System.out.println(Thread.currentThread().getName()+" : i = " + i);
        }
    }


    public static void main(String[] args) throws InterruptedException {
        Thread t = new MyThread06();
        t.start();
        Thread.sleep(100);
        t.interrupt();

    }

}

4, instance variables, and thread safety

线程类中的实例变量针对其他线程有共享和不共享之分

4.1, no shared variables

/**
 * 不共享变量
 */
public class MyThread01 extends Thread {
    private int count = 5;
    
    public MyThread01(){}
    
    /**
     * 构造器,
     * @param name
     */
    public MyThread01(String name) {
        this.setName(name);
    }
    
    @Override
    public void run() {
        while (count> 0 ){
            count--;
            System.out.println(this.currentThread().getName()+" : "+count);
        }
    }

    public static void main(String[] args) {
        Thread t1 = new MyThread01("A");
        Thread t2 = new MyThread01("B");
        Thread t3 = new MyThread01("C");
        t1.start();
        t2.start();
        t3.start();
    }

}

Results of the:

A : 4
C : 4
C : 3
C : 2
C : 1
C : 0
B : 4
A : 3
B : 3
A : 2
A : 1
A : 0
B : 2
B : 1
B : 0

Can know by the results, each thread has a separate instance variable count, they affect each other.

4.2, shared variables

/**
 * 共享变量
 */
public class MyThread02 extends Thread {

    private int count = 5;

    @Override
    public void run() {
        while (count> 0 ){
            count--;
            System.out.println(this.currentThread().getName()+" : "+count);
        }
    }

    public static void main(String[] args) {
        MyThread02 t = new MyThread02();
        Thread t1 = new Thread(t,"A");
        Thread t2 = new Thread(t,"B");
        Thread t3 = new Thread(t,"C");
        t1.start();
        t2.start();
        t3.start();
    }

}

Results of the:

A : 3
A : 1
A : 0
B : 3
C : 2

We can see that this has been an error, we want to be a decline, because in most jvm in count-- is a three-step operation:

  1. Query count value;
  2. Calcd the count-1;
  3. Assigning new values ​​to count;

When this problem when multiple threads operating with a shared variable will be thread-safe.

Solution:

  1. Use the synchronized keyword.
  2. Use AtomicInteger atoms class.

In this way the volatile keyword can not be used, since only volatile to ensure visibility and preventing reordering, does not guarantee atomicity.

These will later elaborate.

5, some common methods

5.1, simple way

/**
 *  简单方法
 */
public class MyThread03 extends Thread {
    @Override
    public void run() {
        //获取当前线程对象的引用
        System.out.println(this.currentThread());

        //获取线程 名称
        System.out.println(this.currentThread().getName());//A
        this.currentThread().setName("B");
        System.out.println(this.currentThread().getName());//B

        //获取线程 Id标识符
        System.out.println(this.currentThread().getId());//12

        //获取线程的 优先级 默认为5 最低优先级1,最高优先级10
        System.out.println(this.currentThread().getPriority());//5

        try {
            //休眠1秒
            Thread.sleep(1000*1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //判断当前线程是否存活
        System.out.println(this.currentThread().isAlive());//ture

    }

    public static void main(String[] args) {
        Thread t = new Thread(new MyThread03(),"A");
        t.start();
    }

}

5.2、setDaemon(boolean on)

5.2.1, the definition

Daemon thread also called service threads, threads other specialized services to the user thread, if another user threads are executed, even mian also finished, the JVM will stop running, then stop running the JVM, a daemon thread will stop execution a.

5.2.2 Set

By setDaemon(ture)Before setting daemon threads, setDaemon (ture) to be placed start

/**
 * 守护线程
 */
public class MyThread04 extends Thread {
    @Override
    public void run() {
        System.out.println(this.currentThread().isDaemon());
        try {
            Thread.sleep(1000*3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("MyThread04");
    }


    public static void main(String[] args) {
        Thread t = new MyThread04();
        //设置为守护线程,其他线程执行完毕,守护线程也会立马推出
        t.setDaemon(true);
        t.start();
        System.out.println("main");
    }
}

5.2.3 application

GC threads

5.3、join()

5.3.1, the use of the join method

The main purpose is to synchronize, it can be a serial parallel programming between threads, call the join method B A thread in the thread, it said that only when B A thread execution thread resumes execution is completed

Example:

/**
 * join
 */
public class MyThread05 implements Runnable {
    @Override
    public void run() {
        for(int i = 0 ; i < 50 ; i++){
            System.out.println(Thread.currentThread().getName() +" : i = " + i);
        }
    }


    public static void main(String[] args) throws InterruptedException {
        MyThread05 t = new MyThread05();
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.start();
        t1.join();
        /**
         * 主线成执行到这个位置放弃执行资格,等到t1执行完毕后再执行
         */
        t2.start();
        for(int i = 0 ; i < 50 ; i++){
            System.out.println(Thread.currentThread().getName() +" : i = " + i);
        }

    }
}

The results: After finished t1, t2 and main alternately performed

Another: the Join process may add parameter indicates how many milliseconds to wait for such calls b.join (100) in the thread A, B represents thread A thread waits 100 milliseconds, then AB alternately performed. join (0), indicates to wait indefinitely, join (0) is equivalent to join ().

First start () and then join ()

5.3.2 implementation principle

Source:

   /**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     *
     * <p> This implementation uses a loop of {@code this.wait} calls
     * conditioned on {@code this.isAlive}. As a thread terminates the
     * {@code this.notifyAll} method is invoked. It is recommended that
     * applications not use {@code wait}, {@code notify}, or
     * {@code notifyAll} on {@code Thread} instances.
     *
     * @param  millis
     *         the time to wait in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

A calling B thread thread join () method is equivalent to wait () method thread A thread calls B, B when the thread is finished (or reached the waiting time), B thread will automatically call their notifyAll () method.

Guess you like

Origin www.cnblogs.com/bigfly277/p/11672084.html