[JAVA]synchronized效率问题

1 简介synchronized

Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块。

参考 http://baike.baidu.com/link?url=G_bdTHKHwX6gcAYNC167sfklp0D4BmcIVnae-MQIn5_PErYpGU2SiGEfeDunGkViGbFDcWPmioElk8KLX3i0La

 

2 关于公平性,是否公平锁。

测试结果

  A  jdk1.5是不公平,但是线程数较少的时候,会看起来公平,而且不公平性没有1.6表现的明显。

  B  jdk1.6是不公平的,因为底层实现主要依靠Lock-Free的队列,基本思路是自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量。

测试代码

 1 public class MainC
 2 {
 3     public static void main(String[] args)
 4     {
 5         System.out.println("6 start");
 6         MainC tc = new MainC();
 7         for (int i = 0; i < 10; i++)
 8         {
 9             Thread1 t1 = tc.new Thread1(tc,i);
10             t1.start();    
11         }
12 
13     }
14     class Thread1 extends Thread
15     {
16         MainC tc = null;
17         int i=0;
18 
19         public Thread1(MainC tc,int i)
20         {
21             this.tc = tc;
22             this.i = i;
23         }
24 
25         @Override
26         public void run()
27         {
28             tc.method1(i);
29         }
30     }
31     public synchronized void method1(int i)
32     {
33         System.out.println("method:" + i);
34         try
35         {
36             Thread.sleep(1000);
37         }
38         catch (InterruptedException e)
39         {
40             e.printStackTrace();
41         }
42 
43     }
44 }

执行结果

Jdk1.5:

5 start

method:0

method:1

method:2

method:3

method:4

method:5

method:6

method:7

method:8

method:9

 

Jdk1.6:

6 start

method:0

method:9

method:5

method:8

method:7

method:6

method:4

method:3

method:2

method:1

 

3 耗时测试

a 本地4G内存 +3.2GHZ CPU+32位win7系统

b 测试结果

   在多线程情况下,jdk1.5较耗时。

   在多线程情况下,jdk1.6耗时比较稳定,而且比较低。

测试代码:

public class MainC
{  static class SynRunner implements Runnable { 
        private long v = 0;
        public synchronized void run() { 
            v = v + 1; 
        } 
    }
    static class LockRunner implements Runnable { 
        private ReentrantLock lock = new ReentrantLock(); 
        private long v = 0;
        public void run() { 
            lock.lock(); 
            try { v = v + 1; 
            } finally { lock.unlock(); } }
    }
    static class Tester { 
        private AtomicLong runCount = new AtomicLong(0); 
        private AtomicLong start = new AtomicLong(); 
        private AtomicLong end = new AtomicLong();
        public Tester(final Runnable runner, int threadCount) { 
            final ExecutorService pool = Executors.newFixedThreadPool(threadCount); 
            Runnable task = new Runnable() { 
                public void run() { 
                    while (true) { 
                        runner.run(); 
                        long count = runCount.incrementAndGet(); 
                        if (count == 1) { 
                            start.set(System.nanoTime()); 
                        } else if (count >= 10000000) { 
                            if (count == 10000000) { 
                                end.set(System.nanoTime()); 
                                System.out.println(runner.getClass().getSimpleName() + ", cost: " 
                                        + (end.longValue()-start.longValue())/1000000 + "ms");                            } 
                                pool.shutdown(); 
                            return; } } } }; 
            for (int i = 0; i < threadCount; i++) { 
                pool.submit(task); } } 
    }
    public static void main(String[] args) { 
        System.out.println("jdk6");
        new Tester(new SynRunner(), 30); 
        //new Tester(new LockRunner(), 10); 
    }


}

 

 

Synchronized 测试结果

 

线程数

1

10

30

50

100

Jdk1.5

jdk5

SynRunner, cost: 335ms

 

jdk5

SynRunner, cost:   22419ms

 

jdk5

SynRunner, cost:   22597ms

 

jdk5

SynRunner, cost:   22715ms

 

jdk5

SynRunner, cost:   22868ms

 

Jdk1.6

jdk6

SynRunner, cost: 323ms

jdk6

SynRunner, cost:   1679ms

 

jdk6

SynRunner, cost:   1766ms

 

jdk6

SynRunner, cost:   1713ms

 

jdk6

SynRunner, cost:   1740ms

 

 

转载于:https://www.cnblogs.com/SKeyC27/p/4861124.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值