thread safety

thread safety


First, thread safety

Thread safety concept:
when multiple threads access a certain class (object or method), this class (object or method) can show correct behavior, then this class (object or method) is thread-safe .

Second, the lock

of the same object 1. The object lock of the same object is synchronized The
synchronized lock is at the object level

package com.study.current.thread.day01;

/**
 * Thread safety concept: When multiple threads access a certain class (object or method), this class (object or method) can show correct behavior, then this class (object or method) is thread-safe.
 */
public class MyThread extends Thread {

	private int count = 5 ;
	
	/**
	 * The role of synchronized: lock, prevent concurrent methods
	 *
	 * synchronized: locks can be added to any object and method, and this code of locking is called "mutual exclusion zone" or "critical zone".
	 */
	public synchronized void run(){
		/**
		 * The order of thread execution is not the order of the code, but the order of CPU allocation
		        When a thread accesses the run method of myThread, it is processed in a queued manner
		        Queuing is based on the order in which CPUs are allocated
		        When a thread wants to execute the code in the synchronized method, it first tries to obtain the lock. If the lock is obtained, execute the
		   Synchronized code body content
		        If the lock cannot be obtained, the thread will continue to try to obtain the lock until it is obtained.
		        And it is multiple threads competing for the lock at the same time
		 */
		this.count -- ;
		System.out.println(Thread.currentThread().getName()+" count:"+count);
	}
	
	public static void main(String[] args) {
		MyThread thread = new MyThread();
		
		Thread t1 = new Thread(thread,"t1");
		Thread t2 = new Thread(thread,"t2");
		Thread t3 = new Thread(thread,"t3");
		Thread t4 = new Thread(thread,"t4");
		Thread t5 = new Thread(thread,"t5");
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		t5.start();
		
	}
	
}



2. Example analysis

without synchronization results:
t2 count: 3
t3 count: 2
t4 count: 1
t1 count: 3
t5 count: 0

and the expected result: count values ​​are output in order, which is very different
------ --------------------------------------
Add synchronized running results:
t1 count:4
t3 count: 3
t2 count: 2
t4 count: 1
t5 count: 0

The count values ​​are output in order, but t1 ~ t5 are not in order, that is, the order of thread execution is not the order of the position of the code,
but whoever grabs the execution right of the CPU first, then who Execute first


2. Object locks

for multiple objects 1. Synchronize object locks for multiple objects

Multiple threads and multiple locks: multiple threads, each thread can get its own designated lock, after obtaining the lock respectively, execute Contents of synchronized method body

package com.study.current.thread.day01;

/**
 * The locks obtained by the synchronized keyword are all object locks, rather than a piece of code or method as a lock, so the thread in the instance code executes first
	Synchronized keyword method, that thread holds the lock Lock of the object to which the method belongs, two objects, the thread obtains two different locks
	they do not affect each other

	In one case, it is the same lock, that is, adding the synchronized keyword to the static method, indicating that the .class class is locked, the class-level lock, and the exclusive .class class
 *
 */
public class MultiThread extends Thread {

	public int num = 0 ; // initialize
	
	public synchronized void printNum(String tag) throws InterruptedException{
		if("a".equals(tag)){
			num = 100 ;
			System.out.println("taga num = 100 ");
			Thread.sleep(1000);
		}else{
			num = 200 ;
			System.out.println("tagb num = 200 ");
		}
		
		System.out.println("tag : "+tag + " num : "+num);
	}
	
	public static void main(String[] args) {
		final MultiThread thread1 = new MultiThread();
		final MultiThread thread2 = new MultiThread();
		
		Thread t1 = new Thread(new Runnable() {
			
			public void run() {
				try {
					thread1.printNum("a");
				} catch (InterruptedException e) {
					e.printStackTrace ();
				}
			}
		});
		
		Thread t2 = new Thread(new Runnable() {
			
			public void run() {
					try {
						thread2.printNum("b");
					} catch (InterruptedException e) {
						e.printStackTrace ();
					}
			}
		});
		
		t1.start();
		t2.start();
	}
}




2. Example analysis

Running results:
taga num = 100
tagb num = 200
tag : b num : 200
tag : a num : 100

is different from the expected tag : a num : 100 after executing tag : a num :
100 because the two threads t1 and t2 are respectively The object locks of two different objects thread1 and thread2 are obtained, and they do not affect each other, so the running results are different from expectations.

3. If you want to maintain inter-process locks,
add class-level locks

package com.study.current.thread.day01;

/**
 * The locks obtained by the synchronized keyword are all object locks, rather than a piece of code or method as a lock, so the thread in the instance code executes first
	Synchronized keyword method, that thread holds the lock Lock of the object to which the method belongs, two objects, the thread obtains two different locks
	they do not affect each other

	In one case, it is the same lock, that is, adding the synchronized keyword to the static method, indicating that the .class class is locked, the class-level lock, and the exclusive .class class
 *
 */
public class MultiThread extends Thread {

	
	public static int num = 0 ; // initialization
	
	/**
	 * Add the static keyword, which is a class-level lock
	 * Avoid concurrent execution between different objects
	 * Different threads acquire locks of different objects and need to wait for each other at runtime
	 *
	 * Without the static keyword, it is an object-level lock
	 * Different threads acquire locks of different objects, and execution does not affect each other
	 *
	 * @param tag
	 * @throws InterruptedException
	 */
	public static synchronized void printNum(String tag) throws InterruptedException{
		if("a".equals(tag)){
			num = 100 ;
			System.out.println("taga num = 100 ");
			Thread.sleep(1000);
		}else{
			num = 200 ;
			System.out.println("tagb num = 200 ");
		}
		
		System.out.println("tag : "+tag + " num : "+num);
	}
	
	public static void main(String[] args) {
		final MultiThread thread1 = new MultiThread();
		final MultiThread thread2 = new MultiThread();
		
		Thread t1 = new Thread(new Runnable() {
			
			public void run() {
				try {
					thread1.printNum("a");
				} catch (InterruptedException e) {
					e.printStackTrace ();
				}
			}
		});
		
		Thread t2 = new Thread(new Runnable() {
			
			public void run() {
					try {
						thread2.printNum("b");
					} catch (InterruptedException e) {
						e.printStackTrace ();
					}
			}
		});
		
		t1.start();
		t2.start();
	}
}



Running result:

taga num = 100
tag : a num : 100
tagb num = 200
tag : b num : 200

Four: Synchronization and Asynchronous

1. Concept
Synchronization :
The concept of synchronization synchronization is sharing, if it is not a shared resource, there is no need to share

Asynchronous:
The concept of asynchronized is independent and not subject to any restrictions on each other.

The purpose of synchronization is for

thread safety, the characteristics of thread safety,
atomicity (synchronization)
visibility

2. Liezi
package com.study.current.thread.day01;

public class MyObject extends Thread {

	public synchronized void method1(){
		System.out.println(this.currentThread().getName());
		try {
			Thread.sleep(4000);
		} catch (InterruptedException e) {
			e.printStackTrace ();
		}
	}
	/**
	 * A thread first holds the Lock lock of the object object
		If thread B calls the synchronized method in the object at this time, it needs to wait. is synchronization
		Thread B can call non-synchronized decorated methods in the object in an asynchronous manner
			
		If method2 is not synchronized, then t1 and t2 are output at the same time, and there is no need to acquire the lock of method2
		Conversely, after t1 is output, it needs to wait 4 s before outputting t2
	 */
	public synchronized void method2(){
		System.out.println(this.currentThread().getName());
	}
	
	public static void main(String[] args) {
		
		final MyObject myO = new MyObject();
		
		Thread t1 = new Thread(new Runnable() {
			
			public void run() {
				myO.method1();
			}
		},"t1");
		
		Thread t2 = new Thread(new Runnable() {
			
			public void run() {
				myO.method2();
			}
		},"t2");
		
		t1.start();
		t2.start();
	}
}



3. Analysis

If method2 is not decorated with synchronized, the
running result: t1 and t2 are output at the same time.
Because there is no lock on method2, there is no need to acquire the lock, that is, asynchronous execution of

add and receive, t1 output 4s after t2 output

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327013354&siteId=291194637