java多线程学习(七)

总结:

本篇主要介绍内部类和多线程以及锁对象变化时候的情况

静态内部类和多线程:

package chapter2.innerTest2;

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

/*
演示innerClass1的method1方法对innerClass2上锁,其他线程只能以同步的方式调用innerClass2中的静态同步方法
同步还是异步,就是判断线程进入时,对象监视器是什么,这个对象是否有锁,这个锁是否被其他线程持有(或者说该线程能否取得该对象锁)
从输出可以看出t1和t2是异步的,但是t1和t3是同步的
输出为:
t2进入innerClass1 的method2方法
t1进入innerClass1 的method1方法
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离开innerClass1 的method2方法
t1离开innerClass1 的method1方法
t3进入innerClass2 的method1方法
k=0
k=1
k=2
k=3
k=4
k=5
k=6
k=7
k=8
k=9
t3离开innerClass2 的method1方法


 */
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 + "进入innerClass1 的method1方法");
				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 + "离开innerClass1 的method1方法");
			}
		}

		public synchronized void method2() {
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName + "进入innerClass1 的method2方法");
			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 + "离开innerClass1 的method2方法");
		}
	}

	static class innerClass2 {
		public synchronized void method1(){
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName + "进入innerClass2 的method1方法");
			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 + "离开innerClass2 的method1方法");
		}
	}
}

2,锁变化

在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间就是同步的;如果分别获得锁对象,这些线程之间就是异步的.

以String作为锁

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;

/*
 * 演示锁对象变化的情况
 * 注释掉main线程的sleep过程
 * a,b线程同时请求lock锁,a先持有,b等待,a,b线程的锁为同一个,都是"123",所以是同步的
 * 输出为:
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;

/*
 * 演示锁对象变化的情况
 * a线程执行的时候,改变了lock的对象,b线程获取锁的时候,和a的锁不同,所以是异步的
 * 输出为:
 * 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();
	}
}

锁对象的属性变化,还是同一个对象,就是同一个锁

package chapter2.setNewPropertiesLockOne;

/*
 * 演示当锁对象的属性变化时,只要还是同一个对象,那么多线程间还是同步的,
 * 和String不同,如果String的值变化,String就是不同的对象,
 * 输出为:
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;
	}
	
}

参考:<java多线程编程核心技术>

猜你喜欢

转载自blog.csdn.net/qq467215628/article/details/80211330