JAVA Concurrent not? How to do, see here (a)

mind Mapping

This time I will be shared by the two articles.

Use thread

There are three ways to use threads:

  • Implement Runnable;
  • Implement Callable Interface;
  • Thread class inheritance.
  • Implement Runnable and Callable

Class interface only as a task that can be run in a thread, the thread is not really in the sense, therefore Finally, you need to call by Thread. It can be understood as the task is thus driven by the thread of execution.

Implement Runnable

We need to implement run () method interface.

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // ...
    }
}

复制代码

Use Runnable instance and then create a Thread instance and then call start Thread instance () method to start a thread.

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

复制代码

Implement Callable Interface

Compared with Runnable, Callable there may be a return value, the return value is encapsulated by FutureTask.

public class MyCallable implements Callable<Integer> {
    public Integer call() {
        return 123;
    }
}

复制代码
public static void main(String[] args) throws ExecutionException, InterruptedException {
    MyCallable mc = new MyCallable();
    FutureTask<Integer> ft = new FutureTask<>(mc);
    Thread thread = new Thread(ft);
    thread.start();
    System.out.println(ft.get());
}

复制代码

Thread class inheritance

It is also a need to implement run () method, but also because the Thread class implements the interface Runable.

When you call the start () method to start a thread, the thread into the virtual machine queue waiting to be scheduled in place, when a thread is scheduled to run this thread will execute () method.

public class MyThread extends Thread {
    public void run() {
        // ...
    }
}

复制代码
public static void main(String[] args) {
    MyThread mt = new MyThread();
    mt.start();
}

复制代码

VS implement the interface inheritance Thread

Implement the interface would be better, because:

  • Java does not support multiple inheritance, so you can not inherit the Thread class inherits another class, but can implement multiple interfaces;
  • Classes may only require an executable on the line, the entire inheritance Thread class too much overhead.

Basic thread mechanism

Executor

Executor manage multiple asynchronous tasks to perform, without the programmer explicitly lifecycle management thread. Asynchronous here means performing a plurality of tasks interfere with each other, does not require synchronization.

There are three main Executor:

  • CachedThreadPool: a task to create a thread;
  • FixedThreadPool: All tasks can only use a fixed-size thread;
  • SingleThreadExecutor: FixedThreadPool 1 corresponding to the size.
public static void main(String[] args) {
    ExecutorService executorService = Executors.newCachedThreadPool();
    for (int i = 0; i < 5; i++) {
        executorService.execute(new MyRunnable());
    }
    executorService.shutdown();
}

复制代码

Daemon

Daemon threads are thread-service program runs in the background, an integral part of the program does not belong.

At the end of all non-daemon threads, the program will terminate, and it will kill all daemon threads.

main () is a non-daemon threads.

Use setDaemon before the thread start () method can set a thread as a daemon thread.

public static void main(String[] args) {
    Thread thread = new Thread(new MyRunnable());
    thread.setDaemon(true);
}

复制代码

sleep()

Thread.sleep (millisec) method will be dormant thread is currently executing, millisec milliseconds.

sleep () may throw InterruptedException, because exceptions can not propagate across threads back to main (), and therefore must be handled locally. Thread thrown other anomalies also need to be handled locally.

public void run() {
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

复制代码

yield()

Calls to static methods Thread.yield () declares the current thread has completed the life cycle of the most important part, you can switch to other threads to execute. This method is just a suggestion thread scheduler, but only recommend other threads with the same priority may be run.

public void run() {
    Thread.yield();
}

``
`
## 中断
一个线程执行完毕之后会自动结束,如果在运行过程中发生异常也会提前结束。
### InterruptedException
通过调用一个线程的 interrupt() 来中断该线程,如果该线程处于阻塞、限期等待或者无限期等待状态,那么就会抛出 InterruptedException,从而提前结束该线程。但是不能中断 I/O 阻塞和 synchronized 锁阻塞。

对于以下代码,在 main() 中启动一个线程之后再中断它,由于线程中调用了 Thread.sleep() 方法,因此会抛出一个 InterruptedException,从而提前结束线程,不执行之后的语句。

```java
public class InterruptExample {

    private static class MyThread1 extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(2000);
                System.out.println("Thread run");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

复制代码
public static void main(String[] args) throws InterruptedException {
    Thread thread1 = new MyThread1();
    thread1.start();
    thread1.interrupt();
    System.out.println("Main run");
}

复制代码
Main run
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at InterruptExample.lambda$main$0(InterruptExample.java:5)
    at InterruptExample$$Lambda$1/713338599.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

复制代码

interrupted()

If a thread's run () method performs an infinite loop and does not comply sleep () throws InterruptedException and other operations, then the calling thread interrupt () method can not be the end of the thread in advance.

But calling interrupt () method will set the thread break off, and now call interrupted () method returns true. Can be used interrupted () method to determine the body of the loop threads are interrupted state, so that the thread end in advance.

public class InterruptExample {

    private static class MyThread2 extends Thread {
        @Override
        public void run() {
            while (!interrupted()) {
                // ..
            }
            System.out.println("Thread end");
        }
    }
}

复制代码
public static void main(String[] args) throws InterruptedException {
    Thread thread2 = new MyThread2();
    thread2.start();
    thread2.interrupt();
}

复制代码

Executor interrupt operation

Executor's call shutdown () method will wait for the thread is finished after the re-closed, but if the call is shutdownNow () method is equivalent to calling interrupt each thread () method.

Use the following Lambda create threads, created the equivalent of an anonymous internal thread.

public static void main(String[] args) {
    ExecutorService executorService = Executors.newCachedThreadPool();
    executorService.execute(() -> {
        try {
            Thread.sleep(2000);
            System.out.println("Thread run");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    executorService.shutdownNow();
    System.out.println("Main run");
}

复制代码
Main run
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at ExecutorInterruptExample.lambda$main$0(ExecutorInterruptExample.java:9)
    at ExecutorInterruptExample$$Lambda$1/1160460865.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

复制代码

If you want to interrupt a thread of Executor, a thread can be submitted by using the submit () method, which returns a Future <?> Object by calling cancel the object (true) method can interrupt threads.

Future<?> future = executorService.submit(() -> {
    // ..
});
future.cancel(true);

复制代码

Mutex synchronization

Java provides two locking mechanisms to control more than one thread mutually exclusive access to shared resources, it is the first JVM implementation of synchronized, and the other is the JDK implementation of ReentrantLock.

synchronized

A sync block

public void func() {
    synchronized (this) {
        // ...
    }
}

复制代码

It only acts on the same object, if the call on the sync block two objects will not be synchronized.

For the following code, the use ExecutorService execute two threads, because the call is synchronized block of the same object, these two threads are synchronized, when a thread enters the synchronized statement block, another thread must wait.

public class SynchronizedExample {

    public void func1() {
        synchronized (this) {
            for (int i = 0; i < 10; i++) {
                System.out.print(i + " ");
            }
        }
    }
}

复制代码
public static void main(String[] args) {
    SynchronizedExample e1 = new SynchronizedExample();
    ExecutorService executorService = Executors.newCachedThreadPool();
    executorService.execute(() -> e1.func1());
    executorService.execute(() -> e1.func1());
}

复制代码
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

复制代码

For the following code, two thread calls the synchronization code blocks of different objects, so do not need to synchronize the two threads. As can be seen from the output results, two cross threads executed.

public static void main(String[] args) {
    SynchronizedExample e1 = new SynchronizedExample();
    SynchronizedExample e2 = new SynchronizedExample();
    ExecutorService executorService = Executors.newCachedThreadPool();
    executorService.execute(() -> e1.func1());
    executorService.execute(() -> e2.func1());
}

复制代码
0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9

复制代码

A synchronization method

public synchronized void func () {
    // ...
}

复制代码

It blocks the synchronization code as applied to the same object.

Synchronization of a class

public void func() {
    synchronized (SynchronizedExample.class) {
        // ...
    }
}

复制代码

Acting on the entire class, which means that two threads call this synchronization statement with a different object classes, will be synchronized.

public class SynchronizedExample {

    public void func2() {
        synchronized (SynchronizedExample.class) {
            for (int i = 0; i < 10; i++) {
                System.out.print(i + " ");
            }
        }
    }
}

复制代码
public static void main(String[] args) {
    SynchronizedExample e1 = new SynchronizedExample();
    SynchronizedExample e2 = new SynchronizedExample();
    ExecutorService executorService = Executors.newCachedThreadPool();
    executorService.execute(() -> e1.func2());
    executorService.execute(() -> e2.func2());
}

复制代码
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

复制代码

Synchronize a static method

public synchronized static void fun() {
    // ...
}

复制代码

Acting on the entire class.

ReentrantLock

ReentrantLock is java.util.concurrent (JUC) package lock.

public class LockExample {

    private Lock lock = new ReentrantLock();

    public void func() {
        lock.lock();
        try {
            for (int i = 0; i < 10; i++) {
                System.out.print(i + " ");
            }
        } finally {
            lock.unlock(); // 确保释放锁,从而避免发生死锁。
        }
    }
}

复制代码
public static void main(String[] args) {
    LockExample lockExample = new LockExample();
    ExecutorService executorService = Executors.newCachedThreadPool();
    executorService.execute(() -> lockExample.func());
    executorService.execute(() -> lockExample.func());
}

复制代码
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

复制代码

Compare

Lock implementation

synchronized is implemented by the JVM, JDK and ReentrantLock is achieved.

performance

The new version of the Java synchronized were a lot of optimization, such as spin locks, etc., synchronized with ReentrantLock roughly the same.

Interruptible wait

When the thread holding the lock release locks for long periods, waiting thread can choose to give up waiting, changed other things.

ReentrantLock can be interrupted, but not synchronized.

Fair locks

Fair lock means multiple threads at the same time waiting for a lock, the lock must be obtained sequentially in chronological order application lock.

The non-synchronized lock fair, ReentrantLock default is unfair, but it can also be a fair

Binding lock multiple conditions

Condition a ReentrantLock can bind multiple objects simultaneously.

Use the Select

Unless ReentrantLock need to use advanced features, or priority use synchronized. This is because a synchronized lock mechanism implemented by the JVM, JVM natively support it, but not all ReentrantLock JDK versions are supported. And do not worry about not using a synchronized release lock deadlock caused problems, because the JVM will secure the release of the lock.

Collaboration between threads

When multiple threads can work together to solve a problem, if some parts must be completed before other parts, we need to be coordinated thread.

join()

Call another thread in the thread join () method, the current thread will be suspended, rather than busy waiting until the target thread terminates.

For the following code, although b thread starts first, but because the call join a thread () method b thread, b threads will wait for a thread to finish before continuing execution, thus finally be able to ensure that the output a thread precedes b thread output.

public class JoinExample {

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

    private class B extends Thread {

        private A a;

        B(A a) {
            this.a = a;
        }

        @Override
        public void run() {
            try {
                a.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("B");
        }
    }

    public void test() {
        A a = new A();
        B b = new B(a);
        b.start();
        a.start();
    }
}

复制代码
public static void main(String[] args) {
    JoinExample example = new JoinExample();
    example.test();
}

复制代码
A
B

复制代码

wait() notify() notifyAll()

Call wait () to wait for a certain condition is met so that the thread, the thread is suspended while waiting, when other threads running makes this condition is met, the other thread calls notify () or notifyAll () to awaken the suspended thread.

They are all part of Object, not part of Thread.

Only be used in synchronous or synchronous control method used in the block, otherwise it will throw IllegalMonitorStateException at runtime.

During use wait () suspends the thread releases the lock. This is because, if there is no release lock, then other threads can not enter the synchronization method of the object or synchronous control block, then it can not execute notify () or notifyAll () to wake up hung threads, causing a deadlock.

public class WaitNotifyExample {

    public synchronized void before() {
        System.out.println("before");
        notifyAll();
    }

    public synchronized void after() {
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("after");
    }
}

复制代码
public static void main(String[] args) {
    ExecutorService executorService = Executors.newCachedThreadPool();
    WaitNotifyExample example = new WaitNotifyExample();
    executorService.execute(() -> example.after());
    executorService.execute(() -> example.before());
}

复制代码
before
after

复制代码

Difference wait () and sleep () is

  • wait () is a method of Object, and sleep () is a static method of the Thread;
  • wait () releases the lock, sleep () will not.

await() signal() signalAll()

Condition java.util.concurrent class library provides classes to achieve coordination between threads, you can call await on Condition () method of the thread to wait another thread calls signal () or signalAll () method wake up waiting threads.

Compared to wait () to wait this way, await () may wait a specified condition, and therefore more flexible.

Use Lock to get a Condition object.

public class AwaitSignalExample {

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void before() {
        lock.lock();
        try {
            System.out.println("before");
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public void after() {
        lock.lock();
        try {
            condition.await();
            System.out.println("after");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

复制代码
public static void main(String[] args) {
    ExecutorService executorService = Executors.newCachedThreadPool();
    AwaitSignalExample example = new AwaitSignalExample();
    executorService.execute(() -> example.after());
    executorService.execute(() -> example.before());
}

复制代码
before
after

复制代码

Thread State

A thread can be in one state, and especially the state where the thread thread state of the Java virtual machine, does not reflect the thread under specific operating system state.

New (NEW)

After creating yet started.

Run (RUNABLE)

Java virtual machine is running. But at the operating system level, it might be running, or it may wait for resource scheduling (for example, processor resources), resources are scheduled to enter operation. It is possible to run state means may be operated, there is no specific resource scheduling operation depends on the underlying operating system.

Blocked (BLOCKED)

Request monitor lock function or to enter the synchronized code block, although other thread has already occupied the monitor lock, so that for the blocked state. To end this state into the other threads so RUNABLE need to release monitor lock.

Wait indefinitely (WAITING)

Waiting for the other thread is explicitly resumed.

Obstruction and wait for the difference is that the obstruction is passive, it is waiting to acquire a monitor lock. The waiting is active, enter by calling Object.wait () methods.

Waiting period (TIMED_WAITING)

Without waiting for other threads explicitly resumed, the system will automatically wake up after a certain time.

When you call to Thread.sleep () deadline for the thread into the wait state, often with "make a thread sleep" described. Call Object.wait () method of the thread enters a waiting period or indefinitely waiting, often with "hang a thread" is described. Sleep and Suspend is used to describe the behavior, obstruction and wait for describing state.

Death (TERMINATED)

After the end of the thread may be the end of his mission, or produce abnormal ended.

Reference herein to talk concurrent (eight) - Fork / Join framework introduced , thread communication , Threads and Locks , Threads and Locks , CS-Notes , three features of the Java memory model , lightweight locks , the Thread State the Java

Guess you like

Origin juejin.im/post/5e5baa7fe51d452701796b5f