Thread (3) thread mutual exclusion technology synchronized

Keywords: Java

Create two threads and observe the errors in Concurrency:

package test;

public class TestThread {
    public static void main(String[] args) {
        Init();
    }

    public static void Init() {


        //Create first thread
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    // TODO Auto-generated method stub
                    System.out.println("yanghao");          
                }           

            }
        }).start();


        //Create a second thread
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    // TODO Auto-generated method stub
                    System.out.println("dingyan");
                }

            }
        }).start();

    }

}

 

Run by test on:

It can be seen that the direct printing string cannot be seen, and there are errors in concurrency. Therefore, print according to characters
 

The code is as follows:

package test;

public class TestThread {
    public static void main(String[] args) {
        Init();
    }

    public static void Init() {


        //Create first thread
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    // TODO Auto-generated method stub
                    //System.out.println("yanghao");
                    Outer("yanghao");
                }           

            }
        }).start();


        //Create a second thread
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    // TODO Auto-generated method stub
                    //System.out.println("dingyan");
                    Outer("dingyan");
                }

            }
        }).start();

    }

    public static void Outer(String str){
        int length = str.length();
        for (int i=0; i<length; i++){
            System.out.print(str.charAt(i));
        }


    }

}

 

The test was as follows:

At this point, the problem arises: when two threads are running at the same time, the output is abnormal and messy

 

To solve this problem, we need to use the synchronized keyword. Let's try:

ackage test;

public class TestThread {
    public static void main(String[] args) {
        Init();
    }

    public static void Init() {


        //Create first thread
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    // TODO Auto-generated method stub
                    //System.out.println("yanghao");
                    Outer1("yanghao");
                }           

            }
        }).start();


        //Create a second thread
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    // TODO Auto-generated method stub
                    //System.out.println("dingyan");
                    Outer2("dingyan");
                }

            }
        }).start();

    }

    public static synchronized void Outer1(String str){
        int length = str.length();
        for (int i=0; i<length; i++){
            System.out.print(str.charAt(i));
        }   
    }

    public static synchronized void Outer2(String str){
        int length = str.length();
        for (int i=0; i<length; i++){
            System.out.print(str.charAt(i));
        }   
    }

}

At this point, the test will find that it is back to normal:

 

 

In daily work, the most used, safest, and ideal thread delay is to use the thread pool technology ScheduledExecutorService

The implementation is similar, as follows:

 

package test;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class TestThread {
    public static void main(String[] args) {
        Init();
    }

    public static void Init() {

        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
        //Create first thread
        pool.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                    Outer1("yanghao");
                }           

            }, 0, 2, TimeUnit.SECONDS);


        //Create a second thread
        pool.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                    Outer2("yanghao");
                }           

            }, 0, 2, TimeUnit.SECONDS);

    }

    public static synchronized void Outer1(String str){
        int length = str.length();
        for (int i=0; i<length; i++){
            System.out.print(str.charAt(i));
        }   
    }

    public static synchronized void Outer2(String str){
        int length = str.length();
        for (int i=0; i<length; i++){
            System.out.print(str.charAt(i));
        }   
    }

}

Test results:

The synchronized keyword is used up, so what is the synchronization lock?

Look at the code:

package test;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class TestThread {
    public static void main(String[] args) {
        Init();
    }

    public static void Init() {

        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
        //Create first thread
        pool.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                    Outer1("yanghao");
                }           

            }, 0, 2, TimeUnit.SECONDS);


        //Create a second thread
        pool.scheduleAtFixedRate(new Runnable() {   
            @Override
            public void run() {
                    Outer2("dingyan");
                }           

            }, 0, 2, TimeUnit.SECONDS);

    }


    private static String token = "";

    public static synchronized void Outer1(String str){
        synchronized (token) {  //Define a lock
            int length = str.length();
            for (int i=0; i<length; i++){
                System.out.print(str.charAt(i));
            }
            System.out.println("");
        }
    }

    public static synchronized void Outer2(String str){
        synchronized (token) {  //Define a lock
            int length = str.length();
            for (int i=0; i<length; i++){
                System.out.print(str.charAt(i));
            }
            System.out.println("");
        }
    }

}
The test shows that synchronization is also achieved:

Synchronization lock is to create a synchronization block at the place of execution and put the code to be executed into it to ensure that when calling the code, it can run independently without interference.

So what's a token?

It's just a lock

The lock for a synchronized code block is arbitrary. As long as different threads execute the same synchronization code block, this lock is set at will.

Posted by poisedforflight on Mon, 30 Dec 2019 10:59:44 -0800