The simplest programming to implement the main volume control of the Windows system

2023-01-23   ES  

The following article comes from the public account “The Road to Programmer’s job search”

We all do development, for time -related classesSimpleDateFormatis no stranger, whether it is the formatting and analysis of time, or the generated UUID has been used.

Presumably everyone must use it like this:

public class SimpleDateFormatTest {
    
    private static final java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args) throws InterruptedException {
    
        System.out.println(sdf.format(new Date()));
    }
}

I received the help from fans today, saying that I used the knowledge of SimpleDateFormat in the work, but the code I finished in the work lies in the code.Multi -line use has been reporting an error.

When we learned the situation, we asked the fans’ consent and had some code to help solve this problem.

After a little adjustment, I wrote a demo, as follows::

public class SimpleDateFormatTest {
    
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static class ParseDate implements Runnable {
    
        int i = 0;
        public ParseDate(int i) {
    
            this.i = i;
        }

        @Override
        public void run() {
    
            try {
    
                Date date = sdf.parse("2020-9-10 12:00:" + i % 60);
                System.out.println("date: " + date);
            } catch (Exception e) {
    
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
        ExecutorService exec = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 1000; i++) {
    
            exec.execute(new ParseDate(i));
        }
    }
}

There is no wrong code that runs a lot of abnormalities when it runs.

After analysis, the error reported was mainly becauseSimpleDateFormat is not thread -safe.

In the source code, we learned that SimpleDateFormat has maintained a Calender object inside it for the formatting date. Therefore, in a multi -threaded environment, multiple threads will use the same Calender object to format the date, leading to data competition, and eventually abnormalities.

So we optimize the code, the first thing we think of isSynchronous lock:

public class SimpleDateFormatTest {
    
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static class ParseDate implements Runnable {
    
        int i = 0;
        public ParseDate(int i) {
    
            this.i = i;
        }

        @Override
        public void run() {
    
            try {
    
                Date date = sdf.parse("2020-9-10 12:00:" + i % 60);
                System.out.println("date: " + date);
            } catch (Exception e) {
    
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
        ExecutorService exec = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 1000; i++) {
    
            exec.execute(new ParseDate(i));
        }
    }
}

After locking, it was found that there was no problem at once.

But we all know that Synchronized locks are not a good solution.

In order not to completely solve this problem without leaving hidden dangers, we have to think about a better wayContinue optimization.

After thinking carefully, we quickly discovered that if you use it every time you use it, a SimpleDateFormat instance can ensure that each instance uses its own Calendar instance.

public class SimpleDateFormatTest {
    
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static class ParseDate implements Runnable {
    
        int i = 0;
        public ParseDate(int i) {
    
             this.i = i;
        }

        @Override
        public void run() {
    
            try {
    
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = sdf.parse("2020-9-10 12:00:" + i % 60);
                System.out.println("date: " + date);
            } catch (ParseException e) {
    
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
        ExecutorService exec = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 1000; i++) {
    
            exec.execute(new ParseDate(i));
        }
    }
}

Excellent everyone should have discovered it, after the modification is changed like thisEvery time you use it, you need a new object, and because there are no other references after use, the object needs to be recycled, and the overhead of the entire process is not small.

Therefore, we can further optimize.

Since you need a new object every time you use it, then we might as well use itThreadLocalTo solve this problem and make each thread create an instance object of the current thread’s SimpleDateFormat.

public class SimpleDateFormatTest {
    
    private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<>();

    public static class ParseDate implements Runnable {
    
        int i = 0;
        public ParseDate(int i) {
    
            this.i = i;
        }

        @Override
        public void run() {
    
            try {
    
                if(threadLocal.get() == null) {
    
                    threadLocal.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
                }
                Date date = threadLocal.get().parse("2020-9-10 12:00:" + i % 60);
                System.out.println("date: " + date);
            } catch (ParseException e) {
    
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
        ExecutorService exec = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 1000; i++) {
    
            exec.execute(new ParseDate(i));
        }
    }
}

Running is correct, and it solves the problem of this fan very well.

Looking back on the entire solution process, synchronous locks are similar to ThreadLocal on solving the problem of multi -threaded concurrency, but ThreadLocal cannot replace the synchronization mechanism.

The

synchronization mechanism is an effective way to solve the concurrent access of the same resources and the communication between the same resources, and the communication between multiple threads.

and ThreadLocal are the data sharing of multiple threads, which is fundamentally shared between multiple threads. Of course, there is no need to synchronize multiple threads.

A copy of a variable binding to the thread for each thread, thereby isolation of the data of multiple threads. Each thread has its own copy of the variable, so there is no need to synchronize the variable.

Write at the end:

When we write code, we can think about one more step, think about why, whether there are other better ways, maybe just changing a idea, a small change, there will be completely different results.

The optimization of the

code is not limited to the significant improvement of performance. The reconstruction of some code can make it readable and scalability, which is also an optimization.

If you see here, if you also need to solve, please leave a message. We will provide solutions and methods as soon as possible.

source

Related Posts

FreeMarker page static

database in Windos backup and delete

Adobe Reader join the bookmark JavaScripts

C ++ The difference between the position order of the position of the global variable and the local variable storage

The simplest programming to implement the main volume control of the Windows system

Random Posts

Spring MVC interceptor response redirect the problem Cannot Forward after Response?

DQN-Experience Realization (Simple)

Markdown special symbol grammar

Barrier’s use

Ubuntu Install Lightweight Desktop