Welcome to follow my wechat official account: Wugi Chat Programming (ID: ESon_15)

Concurrency problems occur when multiple threads operate on the same resource at the same time, such as bank transfers, ticketing systems, etc. To avoid these problems, we can use the synchronized keyword. Here is a summary of common uses of synchronized. Write a program with concurrency problems as follows:

public class TraditionalThreadSynchronized {

	public static void main(String[] args) {
		// An inner class instance object cannot be new in a static method
		//private Outputer outputer = new Outputer();
		new TraditionalThreadSynchronized().init();
	}
	
	private void init(a) {
		final Outputer outputer = new Outputer();
		// Thread 1 prints: duoxiancheng
		new Thread(new Runnable() {			
			@Override
			public void run(a) {
				while(true) {
					try {
						Thread.sleep(5);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					outputer.output1("duoxiancheng");
				}
				
			}
		}).start();;
		
		Thread 2 prints: eson15
		new Thread(new Runnable() {			
			@Override
			public void run(a) {
				while(true) {
					try {
						Thread.sleep(5);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					outputer.output1("eson15");
				}
				
			}
		}).start();;
	}
	
	static class Outputer {
		// A custom string printing method, a character by character printing
		public void output1(String name) {
			int len = name.length();
			for(int i = 0; i < len; i++) {
				System.out.print(name.charAt(i));
			}
			System.out.println(""); }}}Copy the code

The inner Outputer class defines a method to print strings, one character at a time. This makes it easier to see the concurrency problem intuitively, because characters are out of order when there is a problem. Then start two threads in the init method, one printing “duoxiancheng” and the other printing “eson15”. Take a look at the results:

eson15duoxianche

ng eson15 duoxiancheng duoxiancheng eson15 esduoxiancheng on15 duoxiancheng

Has appeared problem, in order to solve this problem, you can use synchronized synchronized code block for synchronous operation of public section, but need to give it a lock, the lock is an object that can be any one object, but the premise is that two threads used must be the same object can lock, it is easy to understand. Add the synchronized block to the output1() method:

static class Outputer {
	private String token = ""; // Define a lock
	public void output1(String name) {
		synchronized(token) // Any object can be used as an argument, but only if the object is the same for both threads
		// If you use name, you can't do it because different threads have different names
		{
			int len = name.length();
			for(int i = 0; i < len; i++) {
				System.out.print(name.charAt(i));
			}
			System.out.println(""); }}}Copy the code

Synchronized (synchronized) : synchronized (synchronized); synchronized (synchronized) We’ll write another output2() method in the Outputer class:

static class Outputer {
	private String token = ""; // Define a lock
	public void output1(String name) {
		synchronized(token) // Any object can be used as an argument, but only if the object is the same for both threads
		{
			int len = name.length();
			for(int i = 0; i < len; i++) {
				System.out.print(name.charAt(i));
			}
			System.out.println(""); }}public synchronized void output2(String name) {
		
		int len = name.length();
		for(int i = 0; i < len; i++) {
			System.out.print(name.charAt(i));
		}
		System.out.println(""); }}Copy the code

Init () ¶ The logic inside the init() method is exactly the same, except that synchronized is added to the method, so one of the two threads in init() calls output1(String name). Another call to the output2(String name) method shows that thread-safety issues arise again. The reason for the problem is not hard to see: synchronized is now used in both methods, but two threads calling two different methods still have a problem, i.e., playing separately… So the problem is this lock, which means they’re not using the same lock!

If we change the token from synchronized to this in output1(), we can run it again. Synchronized (this) {synchronized(this) {… }.

Further down the line, now write a static method output3(String name) in the Outputer class, and let synchronized modify that static method as well.

static class Outputer {
	private String token = ""; // Define a lock
	public void output1(String name) {
		synchronized(token) // Any object can be used as an argument, but only if the object is the same for both threads
		{
			int len = name.length();
			for(int i = 0; i < len; i++) {
				System.out.print(name.charAt(i));
			}
			System.out.println(""); }}public static synchronized void output3(String name) {
		
		int len = name.length();
		for(int i = 0; i < len; i++) {
			System.out.print(name.charAt(i));
		}
		System.out.println(""); }}}Copy the code

Then in the init() method one thread calls the output1() method and the other calls the output3() method. No doubt thread-safety issues will arise again. But how to solve it? Because the static method is loaded when the class is loaded, the lock should be the bytecode object of the class. Change the token to outputer.class. Synchronized (classname.class) {synchronized(classname.class) {… }. A final summary:

  • The lock of a synchronized code block is any object. This lock is set whenever different threads execute the same block of synchronized code.
  • The lock of the synchronization function is fixed to this. When synchronizing with the logic in the synchronization function, the lock in the code block must be this.
  • The lock of a statically synchronized function is the bytecode file object of the class to which the function belongs. This object can be usedthis.getClass()Method, can also be usedThe name of the current class.classSaid.

OK, synchronized summarized so much if there is a mistake, welcome to point out that we progress together!

Also welcome to pay attention to my wechat public number: Programmer private room dishes. I will keep Posting more.