I decided to learn concurrency programming well last week after my supervisor showed me the internal implementation of Kafka using Feature to batch send data.

Because I can only be said to be a novice in multi-threading, I intend to record my learning from the bottom of the Thread step by step.

There are two ways to implement multithreading with Thread. The code is as follows:

Multithreading implementation (inherit Thread class)

/ * * *@Description: Simple multithreading implementation (thread unsafe) *@Author: zhangzhixiang *@CreateDate: 2018/12/21 20:30:54 *@Version: 1.0 * /
public class TestThread extends Thread {
    
    @Override
    public void run(a) {
        for (int i = 0; i<10000;i++) {
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
        TestThread thread = newTestThread(); thread.start(); }}Copy the code

Running results:

0 1 2.. 9999Copy the code

Two, multithreading implementation (implementation Runnable interface)

1, Runnable implementation class

/ * * *@Description: Simple multithreading implementation (thread unsafe) *@Author: zhangzhixiang *@CreateDate: 2018/12/21 20:30:54 *@Version: 1.0 * /
public class RunnalbeImpl implements Runnable {

    @Override
    public void run(a) {
        for(int i = 0; i<10000; i++) { System.out.println(i); }}public static void main(String[] args) {
        RunnableImpl runnable = new RunnableImpl();
        newThread(runnable).start(); }}Copy the code

Operation result: same as above

Above is the first runnable, and the other can be written using JDK8 lambda expressions as follows:

/ * * *@Description: Simple multithreading implementation (thread unsafe) *@Author: zhangzhixiang *@CreateDate: 2018/12/21 20:30:54 *@Version: 1.0 * /
public class TestThread {

    public static void main(String[] args) {
        Count count = new Count();
        Runnable runnable = () -> {
            for (int i = 0; i < 10000; i++) { count.increment(); }}; List<Thread> threads =new ArrayList<>(10);
        for (int i=0; i < 10; i++) {
            Thread thread = new Thread(runnable);
            threads.add(thread);
            thread.start();
        }
        while(true) {
            if(isAllThreadDead(threads)) {// All threads finish running
                System.out.println(count.get());
                break; }}}private static boolean isAllThreadDead(List<Thread> threads) {
        for (Thread thread : threads) {
            if(thread.isAlive()) {
                return false; }}return true; }}Copy the code

Count Count class

/ * * *@Description: Count Count class *@Author: zhangzhixiang *@CreateDate: 2018/12/21 20:38:54 *@Version: 1.0 * /
public class Count {
    
    private int num;
    
    public void increment(a) {
        num++;
    }

    public int get(a) {
        returnnum; }}Copy the code

Running results:

91561
Copy the code

In the third example, 10 threads are running at the same time, and each thread loops 10000 times with an increment of 1 each time. Normal logic should return 100,000, but the actual result is 91561. The reason is that multithreading has three characteristics, namely atomicity, visibility and orderliness. In this case, the count object is a shared resource for 10 threads. Since these 10 threads are concurrent, each count may not be the count obtained by other threads, which will result in an inaccurate value instead of 100,000.

How to implement thread-safe multithreading? See the next article:

Realize thread-safe multithreading through Synchronize