Summary of thread locking knowledge of Java foundation

  • 2021-10-13 07:43:12
  • OfStack

1. synchronized keyword

1. Object locks
a. When using an object lock, be aware of the same object, and while one thread is accessing the code inside the object lock, other threads cannot access it. Note the inaccessible range.
b. But it does not affect the running of the part of the code that does not use object locks.

Object locks fall into two categories: one is called an synchronized code block (objects of ordinary classes in parentheses) and the other is an sybchronized modified ordinary member method. In fact, the two of them can be input converted through this keyword.

2. Class locks
a. When using a class lock, only objects of the same class. While a thread is accessing code inside the class lock, other threads cannot access it. (Note inaccessible ranges)
b. But it does not affect the operation of the part of the code that does not use class locks

Object locks fall into two categories: one is called an synchronized code block (class objects in parentheses) and the other is an sybchronized modified static member method. The two of them can actually be converted through class object input.

Note: There is no relationship between class locks and object locks.

1. Do not use thread locks

If the synchronized keyword is not added, the threads will run interlaced


/**
 *  This class writes 1 A test Method, do not add first synchronized Keyword 
 */
public class A {

	void test() {
		for(int i=0;i<10;i++) {
			System.out.println(" Threads: "+i);
		}
	}
}

/**
 *  Class inheritance Thread , rewrite run Method invocation A In test Method 
 */
public class MyThread1 extends Thread{

	A a;
	
	public void run() {
		a.test();
	}
}

/**
 *  Class inheritance Thread , rewrite run Method invocation A In test Method 
 */
public class MyThread2 extends Thread{

	A a;
	
	public void run() {
		a.test();
	}
}

/**
 *  Test program 
 * /
public class Entrance {

	public static void main(String[] args) {
		
		/**
		 *  Demonstrates interleaving when there is no lock 
		 */
		A a = new A();
		
		MyThread1 t1 = new MyThread1();
		MyThread2 t2 = new MyThread2();
		
		t1.a = a;
		t2.a = a;
		
		t1.start();
		t2.start();
	}

}

 The following operation results are produced: 
 Threads: 0
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 0
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9

2. Use object locks

Change the test method code in the A class to the following code, and the rest remains unchanged. Running the test class can produce the following results


/**
 *  This class writes 1 A test Method, using object locks 
 *  Add code before and after the lock respectively, and the demonstration will not have any impact on the code that does not use the object lock 
 *  And if the object lock is locked, the code behind the object lock will not run 
 */
public class A {

	void test() {
		System.out.println(" Thread start ");
		synchronized(this) {
			for(int i=0;i<10;i++) {
				System.out.println(" Threads: "+i);
			}
		}
		System.out.println(" Thread end ");
	}
}
 Running the test class will produce the following results: (Note: "Thread start" is not the content in the object lock) 

 Thread start 
 Threads: 0
 Threads: 1
 Thread start 
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9
 Threads: 0
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Thread end 
 Threads: 7
 Threads: 8
 Threads: 9
 Thread end 

Using the synchronized direct modification method is equivalent to the entire code within the synchronized (this) modification method


/**
 * synchronized The direct modification method is equivalent to synchronized(this) Decorate all code within a method 
 * test And test1 Methods are equivalent 
 */
public class A {

	synchronized void test() {
		System.out.println(" Thread start ");
			
		for(int i=0;i<10;i++) {	
			System.out.println(" Threads: "+i);	
		}
			
		System.out.println(" Thread end ");
	}
	
	void test1() {
		synchronized (this) {
			System.out.println(" Thread start ");
			
			for(int i=0;i<10;i++) {	
				System.out.println(" Threads: "+i);	
			}
				
			System.out.println(" Thread end ");
		}
	}
}
 The other code is 1 Like, in MyThread1 And MyThread2 Regardless of the call in the test Or test1 The result is that 1 Like, as follows: 

 Thread start 
 Threads: 0
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9
 Thread end 
 Thread start 
 Threads: 0
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9
 Thread end 

Object locks are also useful for different methods (so are class locks)


/**
 *  Class locks are also useful for different methods 
 */
public class A {

//	synchronized void test() {	
//		for(int i=0;i<10;i++) {	
//			System.out.println(" Method test : "+i);	
//		}
//	}
	void test() {	
		synchronized(this) {
			for(int i=0;i<10;i++) {	
				System.out.println(" Method test : "+i);	
			}
		}
	}
	
//	synchronized void test1() {	
//		for(int i=0;i<10;i++) {	
//			System.out.println(" Method test1 : "+i);	
//		}
//	}
	void test1() {
		synchronized(this) {
			for(int i=0;i<10;i++) {	
				System.out.println(" Method test1 : "+i);	
			}
		}
	}
}
MyThread1 Call in test Method, MyThread2 Call in test1 Method, and the result is as follows: 

 Method test : 0
 Method test : 1
 Method test : 2
 Method test : 3
 Method test : 4
 Method test : 5
 Method test : 6
 Method test : 7
 Method test : 8
 Method test : 9
 Method test1 : 0
 Method test1 : 1
 Method test1 : 2
 Method test1 : 3
 Method test1 : 4
 Method test1 : 5
 Method test1 : 6
 Method test1 : 7
 Method test1 : 8
 Method test1 : 9

3. Use class locks

Demonstrates that when the test method in the A class uses an object lock, the object lock has no effect when different objects call the test method


/**
 *  This class writes 1 A test Method, using object locks to demonstrate that no object is called test Method 
 */
public class A {

	void test() {
		synchronized(this) {
			for(int i=0;i<10;i++) {
				System.out.println(" Threads: "+i);
			}
		}
	}
}

MyThread1 And MyThread2 Yes 1 Sample, mainly in the different test procedures 

 Test procedures: 
public class Entrance {

	public static void main(String[] args) {
		
		/**
		 *  Demonstrates using different objects to call test Object locks interleave when the 
		 *  This is not the case with class locks 
		 */
		A a1 = new A();
		A a2 = new A();
		
		MyThread1 t1 = new MyThread1();
		MyThread2 t2 = new MyThread2();
		
		t1.a = a1;
		t2.a = a2;
		
		t1.start();
		t2.start();
	}

}

 Run results: 

 Threads: 0
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 0
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9

Using a class lock changes this situation, and no matter which object is called, as long as the same method is called, the lock will be generated


/**
 *  This class writes 1 A test Method, using object locks to demonstrate that no object is called test Method 
 *  Will class A In this Replace with A.class, The rest of the code remains the same 
 */
public class A {

	void test() {
		synchronized(A.class) {
			for(int i=0;i<10;i++) {
				System.out.println(" Threads: "+i);
			}
		}
	}
}

 Run results: 
 Threads: 0
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9
 Threads: 0
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9

Object locks fall into two categories: one is called an synchronized code block (objects of ordinary classes in parentheses), and the other is an sybchronized modified ordinary member method. In fact, the two of them can be input converted through this keyword.


/**
 *  This class writes 1 A test Method, using object locks to demonstrate that no object is called test Method 
 *  Will class A In this Replace with A.class, The rest of the code remains the same 
 */
public class A {

	void test() {
		synchronized(A.class) {
			for(int i=0;i<10;i++) {
				System.out.println(" Threads: "+i);
			}
		}
	}
}

 Run results: 
 Threads: 0
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9
 Threads: 0
 Threads: 1
 Threads: 2
 Threads: 3
 Threads: 4
 Threads: 5
 Threads: 6
 Threads: 7
 Threads: 8
 Threads: 9

Class lock This object lock has no relationship, does not affect each other and does not interfere with each other


/**
 *  This class writes test Method uses object locks and writes the test1 Method uses class locks 
 */
public class A {
	
	synchronized void test() {
			for(int i=0;i<10;i++) {
				System.out.println(" Method test : "+i);
			}
	}	
	synchronized static void test1() {
		for(int i=0;i<10;i++) {
			System.out.println(" Method test1 : "+i);
		}
	}
}

MyThread1 Call test Method, using object locks, MyThread2 Call test1 Method, using class locks 

 Test program 
public class Entrance {

	public static void main(String[] args) {

		A a1 = new A();
		A a2 = new A();
		
		MyThread1 t1 = new MyThread1();
		MyThread2 t2 = new MyThread2();
		
		/*
		 	 Use the same 1 Object calls test And test1 There will be a staggering phenomenon 
		 	 Call using different objects test And test1 There will also be a staggering phenomenon 
		 */
//		t1.a = a1;
//		t2.a = a1;
		
		t1.a = a1;
		t2.a = a2;
		
		t1.start();
		t2.start();
	}

}

 Run results: 

 Method test : 0
 Method test : 1
 Method test1 : 0
 Method test1 : 1
 Method test1 : 2
 Method test1 : 3
 Method test1 : 4
 Method test1 : 5
 Method test1 : 6
 Method test1 : 7
 Method test1 : 8
 Method test1 : 9
 Method test : 2
 Method test : 3
 Method test : 4
 Method test : 5
 Method test : 6
 Method test : 7
 Method test : 8
 Method test : 9

Related articles: