java中,线程互斥是为了保证在同一时刻,只有一个线程在访问一段特定的代码或者一个特定的变量。java
看一个多线程使用同一个对象操做引发的问题:多线程
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package
com.model.elgin.thread; public class TestThread4 { public static void main( String [] args) { init(); } private static void init(){ final PrintString ps= new PrintString(); //开启2个线程,分别使用同一个ps对象来打印不一样的字符串 new Thread( new Runnable() { @Override public void run() { while (true){ ps.print( "Chinajiangsuchangzhou" ); } } }).start(); new Thread( new Runnable() { @Override public void run() { while (true){ ps.print( "Americanlalala" ); } } }).start(); } } class PrintString{ //按单个字符打印字符串 public void print( String name){ for ( int i = 0 ; i < name.length(); i++) { System.out.print(name.charAt(i)); } System.out.println(); } } |
这时候,能够从结果中偶尔发现这样的输出:并发
咱们发现,2个线程中的不一样的字符串内容出现了错乱,这就是在多个线程同时访问同一个资源(此处为ps对象)时出现的问题。ide
那么这个问题该如何处理呢?this
咱们能够经过对多个线程访问的公共方法或者代码块加锁来实现,保证在同一时刻只有一个线程在访问处理资源。spa
有2种方式来实现锁:.net
1)、在PrintString类的print方法上增长synchronized关键字来给方法加锁。在已有线程在调用此方法的时候,其它的线程不能调用它。线程
2)、经过同步代码块来给一段代码加锁,修改以下:对象
1
2 3 4 5 6 7 8 9 10 11 |
class
PrintString{ //按单个字符打印字符串 public void print( String name){ synchronized ( this ){ for ( int i = 0 ; i < name.length(); i++) { System.out.print(name.charAt(i)); } System.out.println(); } } } |
修改事后,再次运行,上述问题再也不出现。blog
总结:
当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程获得执行。另外一个线程必须等待当前线程执行完这个代码块之后才能执行该代码块。即当一个线程访问object的一个synchronized(this)同步代码块时,其余线程对object中全部其它synchronized(this)同步代码块的访问将被阻塞。
注意:要互斥,必须让锁是同一把。以上的demo中,两个线程都用的是同一个new出来的ps对象,因此是同一个对象。