Java multi-threaded learning (seven)

Summarize:

This article mainly introduces the inner class and multi-threading and the situation when the lock object changes

Static inner classes and multithreading:

package chapter2.innerTest2;

import chapter2.innerTest2.OutClass.innerClass1;
import chapter2.innerTest2.OutClass.innerClass2;

/*
Demonstrate that the method1 method of innerClass1 locks innerClass2, and other threads can only call the static synchronization method in innerClass2 in a synchronized manner
Synchronous or asynchronous is to determine what the object monitor is when the thread enters, whether the object has a lock, and whether the lock is held by other threads (or whether the thread can obtain the object lock)
From the output it can be seen that t1 and t2 are asynchronous, but t1 and t3 are synchronous
The output is:
t2 enters the method2 method of innerClass1
t1 enters the method1 method of innerClass1
j=0
i=0
i=1
j=1
i=2
j=2
i=3
j=3
i=4
j=4
i=5
j=5
j=6
i=6
j=7
i=7
j=8
i=8
j=9
i=9
t2 leaves the method2 method of innerClass1
t1 leaves the method1 method of innerClass1
t3 enters the method1 method of innerClass2
k=0
k=1
k=2
k=3
k=4
k=5
k=6
k=7
k=8
k=9
t3 leaves the method1 method of innerClass2


 */
public class Run {
	public static void main(String[] args) {
		final innerClass1 inc1=new innerClass1();
		final innerClass2 inc2=new innerClass2();
		Thread t1=new Thread(new Runnable() {
			public void run() {
				inc1.method1(inc2);
			}
		}, "t1");
		Thread t2=new Thread(new Runnable() {
			public void run() {
				inc1.method2();
			}
		}, "t2");
		Thread t3=new Thread(new Runnable() {
			public void run() {
				inc2.method1();
			}
		},"t3");
		t1.start();
		t2.start();
		t3.start();
	}

}
package chapter2.innerTest2;

public class OutClass {
	static class innerClass1 {
		public void method1(innerClass2 class2) {
			String threadName = Thread.currentThread().getName();
			synchronized (class2) {
				System.out.println(threadName + "Enter the method1 method of innerClass1");
				for (int i = 0; i < 10; i++) {
					System.out.println("i=" + i);
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace ();
					}
				}
				System.out.println(threadName + "Leaving the method1 method of innerClass1");
			}
		}

		public synchronized void method2() {
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName + "Enter the method2 method of innerClass1");
			for (int j = 0; j < 10; j++) {
				System.out.println("j=" + j);
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace ();
				}
			}
			System.out.println(threadName + "Leaving the method2 method of innerClass1");
		}
	}

	static class innerClass2 {
		public synchronized void method1(){
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName + "Enter the method1 method of innerClass2");
			for (int k = 0; k < 10; k++) {
				System.out.println("k=" + k);
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace ();
				}
			}
			System.out.println(threadName + "Leaving the method1 method of innerClass2");
		}
	}
}

2, lock change

When using any data type as a synchronization lock, it is necessary to pay attention to whether there are multiple threads holding the lock object at the same time. If they hold the same lock object at the same time, these threads are synchronized; if the lock object is obtained separately, These threads are asynchronous.

Use String as lock

package chapter2.setNewStringTwoLock;

public class MyService {
	private String lock = "123";

	public void testMethod() {
		try {
			synchronized (lock) {
				System.out.println(Thread.currentThread().getName() + " beging time=" + System.currentTimeMillis());
				lock = "456";
				Thread.sleep(2000);
				System.out.println(Thread.currentThread().getName() + " end time=" + System.currentTimeMillis());
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace ();
		}
	}
}
package chapter2.setNewStringTwoLock;

/*
 * Demonstrate the change of the lock object
 * Comment out the sleep process of the main thread
 * Threads a and b request lock locks at the same time, a holds first, b waits, the locks of threads a and b are the same, both are "123", so they are synchronized
 * The output is:
a beging time=1525543623392
a end time=1525543625393
b beging time=1525543625394
b end time=1525543627394
 */
public class Run1 {

	public static void main(String[] args) throws InterruptedException {
		MyService ms =new MyService();
		ThreadA ta=new ThreadA(ms);
		ThreadB tb=new ThreadB(ms);
		ta.setName("a");
		tb.setName("b");
		ta.start();
//		Thread.sleep(50);
		tb.start();
	}

}
package chapter2.setNewStringTwoLock;

/*
 * Demonstrate the change of the lock object
 * When thread a executes, the object of the lock is changed. When thread b acquires the lock, it is different from the lock of a, so it is asynchronous
 * The output is:
 * a beging time=1525543489477
b beging time=1525543489527
a end time=1525543491478
b end time=1525543491527
 */
public class Run2 {

	public static void main(String[] args) throws InterruptedException {
		MyService ms =new MyService();
		ThreadA ta=new ThreadA(ms);
		ThreadB tb=new ThreadB(ms);
		ta.setName("a");
		tb.setName("b");
		ta.start();
		Thread.sleep(50);
		tb.start();
	}

}
package chapter2.setNewStringTwoLock;

public class ThreadA extends Thread {
	private MyService ms;
	public ThreadA(MyService ms) {
		super();
		this.ms=ms;
	}
	@Override
	public void run() {
		super.run();
		ms.testMethod();
	}
}
package chapter2.setNewStringTwoLock;

public class ThreadB extends Thread {
	private MyService ms;
	public ThreadB(MyService ms) {
		super();
		this.ms=ms;
	}
	@Override
	public void run() {
		super.run();
		ms.testMethod();
	}
}

If the attributes of the lock object change, it is still the same object, that is, the same lock

package chapter2.setNewPropertiesLockOne;

/*
 * Demonstrate that when the properties of the lock object change, as long as it is still the same object, the multiple threads are still synchronized,
 * Unlike String, if the value of String changes, String is a different object,
 * The output is:
a
end time=1525544321226
b
end time=1525544324227

 */
public class Run {

	public static void main(String[] args) {
		try {
			Service sv=new Service();
			UserInfo uif=new UserInfo();
			ThreadA ta=new ThreadA(sv, uif);
			ta.setName("a");
			ta.start();
			Thread.sleep(50);
			ThreadB tb=new ThreadB(sv, uif);
			tb.setName("b");
			tb.start();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace ();
		}
	}

}
package chapter2.setNewPropertiesLockOne;

public class Service {
	public void serviceMethodA(UserInfo uif){
		synchronized (uif) {
			try {
				System.out.println(Thread.currentThread().getName());
				uif.setUsername("abcabcabc");
				Thread.sleep(3000);
				System.out.println("end time="+System.currentTimeMillis());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace ();
			}
		}
	}
}
package chapter2.setNewPropertiesLockOne;

public class ThreadA extends Thread {
	private Service sv;
	private UserInfo uif;
	public ThreadA(Service sv, UserInfo uif) {
		this.sv=sv;
		this.uif=uif;
	}
	@Override
	public void run() {
		super.run();
		sv.serviceMethodA(uif);
	}
}	
package chapter2.setNewPropertiesLockOne;

public class ThreadB extends Thread {
	private Service sv;
	private UserInfo uif;
	public ThreadB(Service sv, UserInfo uif) {
		this.sv=sv;
		this.uif=uif;
	}
	@Override
	public void run() {
		super.run();
		sv.serviceMethodA(uif);
	}
}	
package chapter2.setNewPropertiesLockOne;

public class UserInfo {
	private String username="a";
	private String passwd="aa";
	public UserInfo() {
		
	}
	public UserInfo(String un,String pwd){
		username=un;
		passwd=pwd;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPasswd() {
		return passwd;
	}
	public void setPasswd(String passwd) {
		this.passwd = passwd;
	}
	
}

Reference: <java multi-threaded programming core technology>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325561799&siteId=291194637