JAVA 并发编程-传统线程互斥技术(Synchronized)(三)

线程互斥是为了保证,同一时刻最多只有一个线程执行该段代码。那么它的出现又是为了解决什么问题呢?账户存取款,在同一时间段只能让一个人进行操作。

 

下面来看一个简单实例(多线程带来的问题):

[java]  view plain  copy
 print ?
  1. public class TraditionalThreadSynchronized {  
  2.   
  3.     /** 
  4.      * @param args 
  5.      */  
  6.     public static void main(String[] args) {  
  7.         new TraditionalThreadSynchronized().init();  
  8.     }  
  9.       
  10.     private void init(){  
  11.         //此方法同时启动两个线程,去调用同一个方法的打印名字  
  12.         final Outputer outputer = new Outputer();  
  13.         new Thread(new Runnable(){  
  14.             @Override  
  15.             public void run() {  
  16.                 while(true){  
  17.                     try {  
  18.                         Thread.sleep(10);  
  19.                     } catch (InterruptedException e) {  
  20.                         e.printStackTrace();  
  21.                     }  
  22.                     outputer.output("zhangxiaoxiang");  
  23.                 }                 
  24.             }  
  25.         }).start();  
  26.           
  27.         new Thread(new Runnable(){  
  28.             @Override  
  29.             public void run() {  
  30.                 while(true){  
  31.                     try {  
  32.                         Thread.sleep(10);  
  33.                     } catch (InterruptedException e) {  
  34.                         e.printStackTrace();  
  35.                     }  
  36.                     outputer.output3("lihuoming");  
  37.                 }  
  38.                   
  39.             }  
  40.         }).start();  
  41.           
  42.     }  
  43.   
  44.     static class Outputer{  
  45.           
  46.         public void output(String name){  
  47.             int len = name.length();  
  48. //          synchronized (Outputer.class)   
  49. //          {  
  50.                 for(int i=0;i<len;i++){  
  51.                     System.out.print(name.charAt(i));  
  52.                 }  
  53.                 System.out.println();  
  54. //          }  
  55.         }  
  56.           
  57.     }  
  58. }  

打印结果为:




解决以上问题:

 

添加synchronized的关键字,即解开注释即可。

 

打印结果:




总结:

 

当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。即当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

注意:要互斥,必须让锁子是同一把。以上的demo中,两个线程都用的是同一个new出来的output,所以output就是同一个对象。

 

详细内容请参看博客[原]02____线程的同步(Synchronized)

 

简答说明:

[java]  view plain  copy
 print ?
  1. public class Test implements Runnable {  
  2.   
  3.     public int cash = 100;  
  4.   
  5.     public synchronized void m() {  
  6.         System.out.println("m查看账户,余额为"+cash);  
  7.         try {  
  8.              Thread.sleep(2000);  
  9.         } catch (InterruptedException e) {  
  10.              e.printStackTrace();  
  11.         }  
  12.         cash = cash - 100;  
  13.         System.out.println("cash1 = " + cash);  
  14.     }  
  15.   
  16.     public synchronized void run() {  
  17.         System.out.println("run查看账户,余额为"+cash);  
  18.         cash += 1000;  
  19.         try {  
  20.             Thread.sleep(5000);  
  21.          } catch (InterruptedException e) {  
  22.              e.printStackTrace();  
  23.          }  
  24.         System.out.println("cash2 = " + cash);  
  25.     }  
  26.   
  27.     public static void main(String[] args) {  
  28.         Test test = new Test();  
  29.         Thread thrad = new Thread(test);  
  30.         thrad.start();  
  31.         test.m();  
  32.     }  
  33. }  

添加synchronized关键字后可以看出。只要m或者run进行对账户进行操作,不论中途多长时间,或者睡眠多长时间,线程都要执行完这个方法以后才会执行其他的方法。两个方法都必须加synchronized关键字,并且两者锁定同一对象(此处锁定的对象是test对象)。也就是说,只要有一个线程进入test对象的任意一个加了锁的方法,其他线程就不能访问这个对象里加了相同锁的方法了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值