`

jdk1.5——多线程操作同一资源(互斥各种写法)

 
阅读更多

 

 

 0 代码案例:

 

package thread;

public class SynchronizedThread {

	/**
	 * 利用打印姓名方法    测试多线程并发执行出现的问题
	 * 多线程下操作同一资源,如果不带锁下,必定出现争抢资源而结果显示异常错误,
	 * 
	 * 任何对象都可以当做是一个门栓,如果要保持同步锁,那么门栓也要是同一个
	 */
	public static void main(String[] args) {
		//final Outputer outputer = new Outputer();
		//final Outputer1 outputer = new Outputer1();
		final Outputer2 outputer = new Outputer2();
		
		Thread thread1 = new Thread(new Runnable(){
			@Override
			public void run() {
				while(true){
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					outputer.out("zhong guo ren");
				}
			}
		});
		thread1.start();
		
		
		Thread thread2 = new Thread(new Runnable(){
			@Override
			public void run() {
				while(true){
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					outputer.out("jieta car");
				}
			}
		});
		thread2.start();
		
		
		
		
	}

}

// 下面写法是表达  一定要找出 那个共同的门栓 ,这才是 多线程下达到同步的 要点,至于是同步放在方法头上 还是放在方法体中,没有很大区别!!!!!


// 没有门栓下 多线程操作统一资源  出现打印名称错乱现象
class Outputer {
	public void out(String name) {
			int len = name.length();
			for(int i=0;i<len;i++){
				System.out.print(name.charAt(i));
			}
			System.out.println();
	}
}

// 如下是同步代码块的两种写法

class Outputer1 {
	String lock = "lock"; // 借助于第三方变量 来作为门栓
	public void out(String name) {
		synchronized (lock) {
			int len = name.length();
			for(int i=0;i<len;i++){
				System.out.print(name.charAt(i));
			}
			System.out.println();
		}
	}
}

class Outputer2 {
	 // 借助于调用者对象 来作为门栓  前提是调用者必须是同一个对象
	public void out(String name) {
		synchronized (this) { 
			int len = name.length();
			for(int i=0;i<len;i++){
				System.out.print(name.charAt(i));
			}
			System.out.println();
		}
	}
}

// 如下是同步方法写法
class Outputer3 {
	 // 同步方法下,门栓是调用方法out的类Outputer3的对象,为了保证同步生效,必须确保不同线程调用此方法的类实例是同一个    
	//  此写法和 Outputer2的写法 是同样的效果
	public synchronized void  out(String name) {
		int len = name.length();
		for(int i=0;i<len;i++){
			System.out.print(name.charAt(i));
		}
		System.out.println();
	}
}

// 如果 out方法是静态方法的话,那么同步代码块的门栓应该是 类对象
class Outputer4 {
	 // 同步方法下,门栓是调用方法out的类Outputer3的对象,为了保证同步生效,必须确保不同线程调用此方法的类实例是同一个    
	//  此写法和 Outputer2的写法 是同样的效果
	public synchronized  static void  out(String name) {
		int len = name.length();
		for(int i=0;i<len;i++){
			System.out.print(name.charAt(i));
		}
		System.out.println();
	}
	
	 // 在方法头上加同步 同时方法是static的 那么门栓只能是这个方法所在类的类字节码:  !!!!!!!!!!!!!
	/*public void out(String name) {
		synchronized (Outputer4.class) { 
			int len = name.length();
			for(int i=0;i<len;i++){
				System.out.print(name.charAt(i));
			}
			System.out.println();
		}
	}*/
}



 

 

1 脑图:

 

 



 

 

 

 

  • 大小: 28.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics