您的位置:首页 > 职场人生

黑马程序员 日记二:线程的互斥的学习

2012-05-02 10:43 225 查看
---------------------- android培训java培训、期待与您交流!
----------------------

多个线程能够实现互斥与同步的关键,在于synchronized这个关键字。通过视频的讲解,可以知道,synchronized使用,可以分为以下几种情况:

1.方法内部分代码的互斥;

2.实现整个方法的互斥;

3.synchronized与static组合时候的特殊处理;

下面将用一个内部类讲解三种情况.

class OutPuter {
		
public void output (String name){
int len = name.length();
for (int i = 0; i < len; i++)  {
System.out.println (name.CharAt (i));
}
System.out.println ();
	}

	}




1.方法内部分代码的互斥

例如,若想把output()方法中,for循环的部分实现互斥,只要在for循环外边加包裹上synchronized即可,包裹后的for循环如下:

synchronized (field){
		for (int i = 0; i < len; i++)  {
			System.out.println (name.CharAt (i));
		}
		System.out.println ();
	
	}




其中,field为一个字段,一般为一个唯一的对象作为字段,例如在Outputer类中定义一个String字符串对象,用这个字符串作为field字段,以此作为字段,出现的问题是,当实例化两个OutPuter的时候,这两个对象的output方法也无法做到同步,此时,field字段可以用this来代之这个类。但是,绝对不能用output()方法传入的形参,因为随着传入参数的不同,而失去同步作用。

2.整个方法的互斥

整个方法的互斥,则是在方法名前加上synchronized关键字,例如:

public synchronized void output (String name){
		int len = name.length();
		for (int i = 0; i < len; i++)  {
			System.out.println (name.CharAt (i));
		}
		System.out.println ();
	
	}



当用这种方法实现互斥的时候,其内部的部分代码,就不能使用synchronized关键字包裹了,避免内外两个synchronized使用同一字段造成死锁。如下方式是不行的,
public synchronized void output (String name){
		int len = name.length();
		synchronized (this){
			for (int i = 0; i < len; i++)  {
				System.out.println (name.CharAt (i));
			}
			System.out.println ();
	
		}
	}




这样实现的互斥,默认检测的字段是this。若在同一个类中两个方法,同时存在两个方法,分别用第一种方式和第二种方式实现互斥,若第一种方式的方法互斥字段为this的话,则这两个方法之间可以实习互斥。如下:

class OutPuter {
	public void output 1(String name){
		int len = name.length();
		Synchronized (this) {
			for (int i = 0; i < len; i++)  {
				System.out.println (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.println (name.CharAt (i));
		}
		System.out.println ();
	}
}




在这个例子中,output1和output2就可以实现互斥。

3.与static关键字一起使用

在静态类中的静态方法的互斥,在第二种情况下,在方法名前添加static关键字,同时内部类要变成外部类或者静态类。

static class OutPuter {
	public void output 1(String name){
		int len = name.length();
		Synchronized (this) {
			for (int i = 0; i < len; i++)  {
				System.out.println (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.println (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.println (name.CharAt (i));
		}
		System.out.println ();
	
	}
	
}




则此时,output1方法和output3方法实现互斥,则output1方法中互斥字段必须为OutPuter.class,因为静态方法之和字节码关联。

另外,在教程中,可以知道另外一个知识点,就是内部类不能在静态方法中进行实例化,必须调用外部类的方法,在该方法中对内部类进行实例化。

---------------------- android培训java培训、期待与您交流!
----------------------

详细请查看:http://edu.csdn.net/heima






                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: