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

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

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

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

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

3.synchronizedstatic组合时候的特殊处理;

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

	
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 ();
	}
}


在这个例子中,output1output2就可以实现互斥。

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







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值