Dark Horse programmer--java Basics-Multithreading | thread synchronization

Source: Internet
Author: User

--java Training, Android training, iOS training,. NET training look forward to sharing with you! ——

Multithreading basics, thread synchronization 1. Multithreading Basics 1.1. Process and Thread 1.1.1. What is a process

A process is an area of memory that contains some resources. The operating system uses the process to divide its work into functional units. One or more execution units contained in a process are called threads. The process also has a private virtual address space that can be accessed only by the threads it contains. A thread can only belong to a process and it can only access resources owned by that process. When the operating system creates a process, the process automatically requests a thread that is called the main thread or the first. Several threads in the operating system are running "at the same time." Typically, every application running on the operating system runs in a process, such as Qq,ie, and so on.
Note: The process does not run at the same time in real sense, but concurrently. We will specify later.

1.1.2. What is a thread

A thread is a sequence of processes that executes a stream. Multiple threads of the same class share a piece of memory space and a set of system resources, and the thread itself has a stack for the execution of the program. Threads are less loaded when switching, so a thread is also known as a light-load process. A process can contain multiple threads.
Note: Switching--a phenomenon that occurs when a thread is concurrency, is explained later when the concurrency is explained.

1.1.3. The difference between a process and a thread

A process has at least one thread. The thread's dividing scale is smaller than the process, which makes the multi-thread procedure high concurrency. In addition, the process has a separate memory unit during execution, and multiple threads share memory, which greatly improves the efficiency of the program operation.
The difference between a thread and a process during execution is that each individual thread has a program run entry, sequence of sequence execution, and exit of the program. However, threads cannot be executed independently, and must be dependent on the application, which provides multiple threads of execution control.
From a logical point of view, the meaning of multithreading is that in an application, multiple execution parts can be executed concurrently. However, the operating system does not consider multiple threads as separate applications for scheduling and managing processes and allocating resources.

1.1.4. Thread-Use scenarios

Threads are typically used in situations where multiple tasks need to be completed simultaneously in a program. We can define each task as a thread that allows them to work together.
For example, when we play a game, the game is run by the operating system, so it runs in a separate process, and in the game we will hear some background music, a character moving, some brilliant animation, etc., which occur at the same time in the game, but in fact, Playing music is done independently in one thread, moving a character, and playing some effects on separate threads. These things we can't do in a single thread.
It can also be used in a single thread, but using multithreading can be a faster situation. such as downloading files.
Like thunder, we'll try it. It will open a number of nodes to download a file at the same time.

1.1.5. Concurrency principle

We know from the above sections that both the process and the thread are running concurrently, so what is concurrency?
Multiple threads or processes running "at the same time" are just a manifestation of our senses. In fact, processes and threads are run concurrently, and the thread scheduling mechanism of the OS divides the time into many time fragments (time slices) that are distributed as evenly as possible to the running program, the thread or process that gets the CPU time slice is executed, and the others wait. The CPU then switches back and forth on these processes or threads. All processes and threads on the micro are walking and stopping, macro-running, which is called concurrency, but not in the absolute sense of "simultaneous occurrence."
Note 1: This is done because there is only one CPU at a time. But with the development of the computer, there is a multi-core CPU, such as two cores of CPU can realize the real sense of 2 threads running simultaneously, but because the CPU time fragment assigned to that process or thread is determined by the thread scheduling, so not necessarily two threads belong to the same process, Anyway, we just need to know that a thread or process is running concurrently.
Note 2:os-operating system we call: Operating system
Note 3: The thread scheduling mechanism is a program provided by the OS for concurrent processing. The Java Virtual machine itself also provides a thread scheduling mechanism to mitigate the additional burden of OS switching threads.

1.1.6. Thread Status

For a program, we actually care about threads rather than processes. What we learned from the above is that we know what threads are and how they relate to concurrency. So let's look at the various states of a thread in its life cycle:

Figure-1
NEW: When we create a thread, the thread is not included in the thread schedule and is in a new state.
Runnable: When the thread's Start method is called, the thread takes control of the thread dispatch, which is in a running state and waits for the allocated time fragment to run concurrently.
Running: When the thread is assigned to a time fragment, it is run by the CPU, which is the thread in the Running state.
Blocked: When a thread is running, a blocking behavior can occur, such as waiting for the user to enter information. However, the blocking state is not a hundred-percent occurrence, depending on whether the code has related requirements.
Dead: When a thread's task is complete, or an uncaught exception is thrown during the run, the thread ends, waits for GC to recycle

1.2. Create thread 1.2.1. Use thread to create a line and start a thread

The Java.lang.Thread class is a thread class in which each instance represents a thread that can run concurrently. We can define a specific thread by inheriting the class and overriding the Run method. The purpose of overriding the Run method is to define the logic that the thread will execute. Invokes the thread's start () method instead of calling the run () method directly when the thread is started. The start () method incorporates the current thread into the thread schedule so that the current thread can start running concurrently. When a thread acquires a time fragment, it automatically starts executing the logic in the Run method.
For example:

publicclass TestThread extends Thread{        @Overridepublic void run(){for(int i=0;i< span>100;i++){                System.out.println("我是线程");}}}

To create and start a thread:

    …    Threadthread=newTestThread();//实例化线程     thread.start();//启动线程     …

When the start () method is called, the Run method executes quickly.

1.2.2. Creating and starting a thread with runnable

Implement the Runnable interface and override the Run method to define the thread body and then pass the runnable instance to and start the thread when the thread is created.
The advantage of doing this is that you can decouple the thread from the task that the thread is performing, while Java is single-inheritance, and defining a class to implement the Runnable interface is a better way to implement other parent classes or interfaces. Because the interface is a multi-inheritance relationship.
For example:

publicclass TestRunnable implements Runnable{        @Overridepublicvoidrun(){for(int i=0;i< span>100;i++){                System.out.println("我是线程");}}}

How to start a thread:

    …    =newTestRunnable();    Threadthread=newThread(runnable);//实例化线程并传入线程体     thread.start();//启动线程     …
1.2.3. Creating a thread with an internal class

Often we can create threads in an anonymous inner class, which simplifies the complexity of writing code, which we typically create when a thread needs only one instance.
For example:
Inherit the thread method:

    Threadthread=newThread(){//匿名类方式创建线程         publicvoid run(){        //线程体            }    };    thread.start();//启动线程    

Runnable Way:

    =newRunnable(){//匿名类方式创建线程         publicvoid run(){        }    };    Threadthread=newThread(runnable);    thread.start();//启动线程 
1.3. Thread Operation API1.3.1. Thread.CurrentThread method

The static method of thread CurrentThread method can be used to get the thread running the current code fragment.

Thread current = Thread.currentThread();

1.3.2. Getting thread information

Thread provides methods for getting thread information:
long getId(): Returns the identifier of the thread
String getName(): Returns the name of the thread
int getPriority(): Returns the priority of a thread
Thread.state getState(): Gets the state of the thread
boolean isAlive(): Tests whether the thread is active
boolean isDaemon(): Tests whether a thread is a daemon thread
boolean isInterrupted(): Tests whether the thread has been interrupted
For example:

Publicclass Testthread {publicstatic void main (string[] args) {Thread current = thread. CurrentThread();Long id = current. GetId();String name = current. GetName();int priority = Current. GetPriority();Thread. StateState = Current. GetState();Boolean isAlive = current. IsAlive();Boolean Isdaemon = current. Isdaemon();Boolean isinterrupt = current. isinterrupted();System. out. println("ID:"+id);System. out. println("Name:"+name);System. out. println("Priority:"+priority);System. out. println("state:"+state);System. out. println("isAlive:"+isalive);System. out. println("Isdaemon:"+isdaemon);System. out. println("Isinterrupt:"+isinterrupt);}}
1.3.3. Thread Priority

Thread switching is controlled by thread scheduling, and we cannot intervene through code, but we can maximize the chance of a thread acquiring a time slice by increasing the priority of the thread.
The priority of the thread is divided into 10 levels, with values of 1-10, of which 1 is the lowest and 10 is the highest. The thread provides 3 constants to represent the lowest, highest, and default precedence:
Thread.MIN_PRIORITY,
Thread.MAX_PRIORITY,
Thread.NORM_PRIORITY
The priority is set in the following way:

void setPriority(int priority)

1.3.4. Daemon Threads

There is no difference between a daemon thread and a normal thread, and we just need to set it up with the method provided by thread:
void setDaemon(boolean )
When the argument is true, the thread is the daemon thread.
The daemon thread is characterized by the forced termination of all daemon threads when only the daemon is left in the process.
The GC is running on a daemon thread.
It is important to note that the set thread is the background thread to be set before the thread is started.

    Thread daemonThread =newThread();    daemonThread.setDaemon(true);    daemonThread.start();
1.3.5. Sleep method

The static method of thread sleep is used to bring the current thread into a blocking state:

static void sleep(long ms)
This method causes the current thread to enter the blocking state for a specified millisecond, and when the specified millisecond is blocked, the current thread re-enters the runnable state, waiting for the time slice to be allocated.
The method declaration throws a interruptexception. So you need to catch this exception when using this method.
Example: Electronic Clock Program

void main(String[] args){        SimpleDateFormat sdf=newSimpleDateFormat("hh:mm:ss");while(true){            System.out.println(sdf.format(newDate()));try{                Thread.sleep(1000);//每输出一次时间后阻塞1秒钟}catch(InterruptedException e){                e.printStackTrace();}}}

Note: The program may have a "jumping seconds" phenomenon, because the blocking of a second after the thread is not immediately back to the running state, but out of runnable state, waiting for the time slice. Then the waiting time is "error". So the above program does not execute the output every other second in a strict sense.

1.3.6. Yield method

static method of thread yield:

static void yield()
This method is used to enable the current thread to voluntarily let go of the secondary CPU time slice back to the runnable state, waiting to allocate time slices.

1.3.7. Join method

Thread's method join:

void join()
This method is used to wait for the current thread to end. This method is a blocking method.
The method declaration throws interruptexception.
For example:

void main(String[] args){final Thread t1 =newThread(){publicvoidrun(){//一些耗时的操作}};        Thread t2 =newThread(){publicvoidrun(){try{                    t1.join();//这里t2线程会开始阻塞,直到t1线程的run方法执行完毕}catch(InterruptedException e){                    e.printStackTrace();}//以下是当前线程的任务代码,只有t1线程运行完毕才会运行。}};}
1.4. Thread synchronization 1.4.1. Synchronized keywords

"Thread concurrency Security Problem" occurs when multiple threads concurrently read and write to the same critical resource
Common Critical resources:
multithreaded shared instance variables
Multi-threaded shared static public variables
To solve a thread-safety problem, you need to change the asynchronous operation into a synchronous operation. What is synchronization? So let's take a look at what is synchronous and what is asynchronous.
The so-called asynchronous operation refers to multi-threaded concurrent operations, the equivalent of the various dry.
The so-called synchronous operation refers to a sequence of operations, the equivalent of you do after I do.
In Java, there is a keyword named: synchronized, which is a synchronous lock used to turn a piece of code into a synchronous operation to resolve thread concurrency security issues.

1.4.2. Lock mechanism

Java provides a built-in locking mechanism to support atomicity:
Synchronous code block (synchronized keyword), a synchronous code block consists of two parts: a reference to an object as a lock, and a block of code that is protected by this lock.

synchronized(同步监视器—锁对象引用){//代码块}

If all the code in the method needs to be synchronized, you can also lock the method directly.
Each Java object can be used as a lock that implements synchronization, the thread gets the lock automatically before it enters the synchronization code block, and how to release the lock when exiting the synchronization code block, regardless of whether it exits the lock through a normal path or exits by throwing an exception. The only way to get a built-in lock is to enter a synchronous code block or method protected by this lock.

1.4.3. Selecting the appropriate lock object

Using synchroinzed requires a lock object to be locked to ensure thread synchronization.
Then this object should be aware that multiple threads that need to be synchronized should see the same object reference when accessing the synchronization block. Otherwise, the sync effect is not reached. Usually we use this as the lock object.

1.4.4. Selecting the appropriate lock range

When you use synchronous blocks, you should try to reduce the synchronization scope as much as possible to increase the concurrency of execution efficiency.

1.4.5. Static method Lock

When we lock a static method, such as:

void xxx(){        ….}

Then the object that the method locks is the class object. Each class has a unique class object. Gets the way the class object is: Class name.
Static methods and non-static methods declare the synchronized, and they are non-mutually exclusive relationships. The reason is that a static method locks a class object instead of a static method lock, which is the object that the current method belongs to.

1.4.6. Wait and Nofify

There is a need to coordinate work between multithreading.
For example, a browser that displays a picture of Displaythread wants to perform the task of displaying the picture, and must wait for the download thread downloadthread to download the picture. If the picture has not been downloaded, displaythread can pause, when Downloadthread completed the task, then notify Displaythread "picture ready, can show", at this time, Displaythread continue to execute.
The above logic simply says: If the condition is not satisfied, then wait. When the condition is met, the thread that waits for the condition is awakened. In Java, the implementation of this mechanism relies on wait/notify. The wait mechanism is closely related to the lock mechanism.

1.4.7. Thread-safe APIs and non-thread-safe APIs

The previously learned API has classes that are designed to be thread-safe and non-thread-safe:
StringBuffer is a synchronous synchronized append ();
StringBuilder is not a synchronous append ();
Relatively stringbuffer is less than StringBuilder in processing, but it is thread-safe. Preference should use StringBuilder when there is no concurrency.
The same:
Vectors and Hashtable are thread-safe, while ArrayList and HashMap are not thread-safe.
For collections, collections provides several static methods that can convert a collection or map to thread-safe:
For example:
Collections.synchronizedList(): Gets the thread-safe list collection
Collections.synchronizedMap(): Get a thread-safe map

...    List< span>String< list =new ArrayList< span>String<();    list.add("A");    list.add("B");    list.add("C");    list = Collections.synchronizedList(list);    //将ArrayList转换为线程安全的集合    System.out.println(list);    //[A,B,C] 可以看出,原集合中的元素也得以保留...
1.4.8. Implementing a thread pool using Executorservice

When a program creates a large number of threads and destroys them at the end of a task, it can cause excessive resource consumption and the risk of over-switching threads, potentially causing the system to crash. For this reason we should use a thread pool to solve this problem. The
Executorservice is a Java-provided class for managing the thread pool. The
thread pool has two main functions:
① Control Threads
② reusing threads
thread pool concept : First create some threads, their collections are called thread pools, and when the server accepts a customer request, Takes an idle thread out of the thread pool and does not close the thread after the service is finished, but it also returns the thread to the thread pool.
in the online pool programming mode, the task is submitted to the entire thread pool, not directly to a thread, the thread pool after the task, it is internally to find a free thread, and then to the internal idle thread, the task is submitted to the entire thread pool, a thread can only perform a task at the same time, But you can submit multiple tasks to a thread pool at the same time
the thread pool has the following implementation strategies:
Executors.newcachedthreadpool ()
Create a thread pool that can create new threads as needed. However, they are reused when the previously constructed threads are available.
executors.newfixedthreadpool (int nthreads)
Creates a thread pool that can reuse fixed thread collections to run these threads in a shared, unbounded queue.
executors.newscheduledthreadpool (int corepoolsize)
Creates a thread pool that can schedule a command to run after a given delay or execute it on a regular basis.
executors.newsinglethreadexecutor ()
Creates a Executor that uses a single worker thread to run the thread in a unbounded queue. The
can use some kind of thread pool based on actual requirements. For example, create a thread pool with a fixed number of threads:

...    ExecutorService threadPool= Executors.newFixedThreadPool(30);//创建具有30个线程的线程池    Runnable r1 =newRunable(){public void run(){//线程体}};    threadPool.execute(r1);//将任务交给线程池,其会分配空闲线程来运行这个任务。...
1.4.9. Using Blockingqueue

The

Blockingqueue is a double-buffered queue.
in multi-threaded concurrency, we can use queue if we need to use queues, but to solve one problem is synchronization, but synchronization reduces the efficiency of concurrent operations on the queue. The
Blockingqueue uses two queues internally, allowing two threads to store one queue at a time, one for the fetch operation. Improve the efficiency of queue access while ensuring concurrency security. The
double-buffered queue has several implementations:
①arrayblockingdeque: A blockingdeque of the specified size, whose constructor must take an int parameter to indicate its size. The objects it contains are sorted in FIFO (first in, first out) order.
②linkedblockingdeque: Blockingdeque of variable size, if its constructor takes a specified size parameter, the resulting blockingdeque has a size limit, without the size parameter, The size of the generated blockingdeque is determined by Integer.max_value. The objects it contains are sorted in FIFO (first in, first out) order.
③priorityblockingdeque: Similar to Linkedblockdeque, but the sort of objects it contains is not FIFO, but is based on the natural sort order of the objects or the order in which the comparator of the constructors are determined.
④synchronousqueue: A special blockingqueue, the operation of which must be put and take the alternate completion.
For example:

void main(String[] args){        BlockingQueue< span>String< queue=new LinkedBlockingDeque< span>String<();try{//queue.offer("A");//立即向队列末尾追加元素/*             * 向队列末尾追加元素,指定可延迟5秒。             * 若5秒钟内成功将元素加入队列返回true             * 若超时后元素仍然没有加入队列则返回flase             */            queue.offer("A",5,TimeUnit.SECONDS);}catch(InterruptedException e){            e.printStackTrace();}        System.out.println(queue.poll());}

This is the end of the article.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Black Horse Programmer--java Basics-Multithreading | thread synchronization

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.