---------------------- 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培训、期待与您交流! ----------------------