单例模式 多线程并发控制

单例模式应用场景之一: 确保共享的数据,共享的操作,在多线程下,线程安全。其实现方式是:控制资源的使用,通过线程同步来控制资源的并发访问;

疑问:一直都不理解为什么可以做到,不使用单例,为什么又做不到?

 

一、设计测试场景:

1、单例测试场景

单例类:

public class ShareResourceSingleton {

       private static ShareResourceSingleton instance = new ShareResourceSingleton();

       private ShareResourceSingleton() {

       }

       public static ShareResourceSingleton getInstance() {

              return instance;

       }

       public synchronized void testShareResourcePrototype() {

              System.out.println("testShareResourcePrototype" + Thread.currentThread().getName());

              try {

                     Thread.currentThread().sleep(5500);

              } catch (InterruptedException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

              System.out.println("testShareResourcePrototype" + Thread.currentThread().getName() + "sleep over");

       }

}

 

测式主类

public class TestThread {

       public static void main(String[] args) {        

              Thread t1 = new Thread1();

              Thread t2 = new Thread1();

              t1.start();

              t2.start();

       }

}

 

 

 

线程1

public class Thread1 extends Thread{

       public void run(){

              /*ShareResourcePrototype shareResourcePrototype = new ShareResourcePrototype();

              shareResourcePrototype.testShareResourcePrototype();*/

              ShareResourceSingleton shareResourceSingleton = ShareResourceSingleton.getInstance();

              shareResourceSingleton.testShareResourcePrototype();

       }

}

 

输出:

testShareResourcePrototypeThread-0

testShareResourcePrototypeThread-0sleep over

testShareResourcePrototypeThread-1

testShareResourcePrototypeThread-1sleep over

 

2、多例测试场景

多例类:

public class ShareResourcePrototype {

       private int i = 0;

       public synchronized void testShareResourcePrototype() {

              System.out.println("testShareResourcePrototype" + Thread.currentThread().getName());

              try {

                     Thread.currentThread().sleep(5500);

              } catch (InterruptedException e) {

                     // TODO Auto-generated catch block

                     e.printStackTrace();

              }

              System.out.println("testShareResourcePrototype" + Thread.currentThread().getName() + "sleep over");

       }

}

 

 

线程1

public class Thread1 extends Thread{

       public void run(){

              ShareResourcePrototype shareResourcePrototype = new ShareResourcePrototype();

              shareResourcePrototype.testShareResourcePrototype();

       /*     ShareResourceSingleton shareResourceSingleton = ShareResourceSingleton.getInstance();

              shareResourceSingleton.testShareResourcePrototype();*/

       }

}

 

输出:

testShareResourcePrototypeThread-0

testShareResourcePrototypeThread-1

testShareResourcePrototypeThread-0sleep over

testShareResourcePrototypeThread-1sleep over

 

 

二、结论:

1、以上输出说明,在使用单例时,同步代码块仅能被一个线程访问,直到线程执行完同步代码块,释放锁。其它线程才能进入此代码块。这样就达到了控制并发访问的目的,实现了线程安全

所以使用单例+线程同步 ,可以满足一些特定的场景,比如:打印,文件访问等需要全局控制并发访问需求

2、使用多例时,同步代码块没有起到互斥的作用,可以被多线程同时访问

 

回答之前的疑问:

不理解,并不是不理解单例模式,而是不理解synchronized 这个的作用。

 synchronized 只会锁定调用其同步方法的那个对象,意思是,多线程只有使用同一个对象(实例)时,才可以达到同步方法互斥访问的效果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值