当前位置:编程学习 > JAVA >>

关于JAVA多线程并发synchronized的测试与合理使用

 在项目开发中, 或许会碰到JAVA的多线程处理, 为保证业务数据的正常, 必须加上锁机制,  常用的处理方法一般是加上synchronized关键字, 目前JDK版本对synchronized已经做了很好的优化,  我们不用再考虑其性能,  但在实际使用中,  往往由于处理不当,  导致系统性能的严重下降, 那么该如何合理的使用synchronized,  必须对其使用方式有个全面了解, 在网上搜寻的资料, 给出的是四种使用方式, 其实可总结为两种, 一个是同步代码块, 一个是同步方法体, 那么该如何使用, 请看下面的测试:
  准备两个方法,  对同一个变量做加法, 再对每个方法, 分别开十个线程执行:
[java]  
public class ThreadUnit  
{  
    private int i = 0;  
  
    private Object obj1 = new Object();  
  
    private Object obj2 = new Object();  
  
    public synchronized Integer doAdd1(Long start) throws Exception  
    {  
  
        Thread.sleep(100);  
        ++i;  
        Thread.sleep(100);  
  
        return i;  
  
    }  
  
    public Integer doAdd2(Long start) throws Exception  
    {  
  
        Thread.sleep(100);  
        ++i;  
        Thread.sleep(100);  
  
        return i;  
    }  
}  
 
相关代码:
[java]  
                // 十个线程同时执行方法2  
for (int i = 0; i < 10; i++)  
{  
    new Thread(new MessageThread(1, threadUnit)).start();  
}  
// 十个线程同时执行方法2  
for (int j = 0; j < 10; j++)  
{  
    new Thread(new MessageThread(2, threadUnit)).start();  
}  
线程处理:
[java]  
public void run()  
        {  
  
            try  
            {  
                if (operate == 2)  
                {  
                    long start = System.currentTimeMillis();  
                    int i = threadUnit.doAdd2(start);  
                    long takeTime = System.currentTimeMillis() - start;  
                    System.out.println("doAdd2() => i=" + i + ", spendTime=" + takeTime + "ms");  
                    spendTime += takeTime;  
                }  
                else  
                {  
                    long start = System.currentTimeMillis();  
                    int i = threadUnit.doAdd1(start);  
                    long takeTime = System.currentTimeMillis() - start;  
                    System.out.println("doAdd1() => i=" + i + ", spendTime=" + takeTime + "ms");  
                    spendTime += takeTime;  
                }  
  
            }  
            catch (Exception e)  
            {  
                e.printStackTrace();  
            }  
        }  
 
 
 运行结果:
1. 在两个方法体上都加上synchronized
[java]  
public synchronized Integer doAdd1(Long start) throws Exception  
[java]  
public synchronized Integer doAdd2(Long start) throws Exception  
执行结果:
[html]  
doAdd1() => i=1, spendTime=203ms  
doAdd2() => i=2, spendTime=406ms  
doAdd2() => i=3, spendTime=609ms  
doAdd2() => i=4, spendTime=796ms  
doAdd2() => i=5, spendTime=1000ms  
doAdd2() => i=6, spendTime=1203ms  
doAdd2() => i=7, spendTime=1406ms  
doAdd2() => i=8, spendTime=1609ms  
doAdd2() => i=9, spendTime=1812ms  
doAdd2() => i=10, spendTime=2015ms  
doAdd2() => i=11, spendTime=2218ms  
doAdd1() => i=12, spendTime=2406ms  
doAdd1() => i=13, spendTime=2609ms  
doAdd1() => i=14, spendTime=2812ms  
doAdd1() => i=15, spendTime=3015ms  
doAdd1() => i=16, spendTime=3218ms  
doAdd1() => i=17, spendTime=3421ms  
doAdd1() => i=18, spendTime=3625ms  
doAdd1() => i=19, spendTime=3828ms  
doAdd1() => i=20, spendTime=4015ms  
花费时间:42226ms  
都是有序执行, 变量值没有产生错乱, 但花费时间42226ms
 
2.在doAdd1方法上加上synchronized, doAdd2不加.
[java] 
public synchronized Integer doAdd1(Long start) throws Exception  
执行结果:
[java] 
doAdd1方法加上synchronized:  
doAdd1() => i=9, spendTime=204ms  
doAdd2() => i=9, spendTime=188ms  
doAdd2() => i=9, spendTime=188ms  
doAdd2() => i=9, spendTime=188ms  
doAdd2() => i=9, spendTime=188ms  
doAdd2() => i=9, spendTime=188ms  
doAdd2() => i=9, spendTime=188ms  
doAdd2() => i=9, spendTime=188ms  
doAdd2() => i=9, spendTime=188ms  
doAdd2() => i=9, spendTime=188ms  
doAdd2() => i=9, spendTime=188ms  
doAdd1() => i=10, spendTime=391ms  
doAdd1() => i=11, spendTime=610ms  
doAdd1() => i=12, spendTime=813ms  
doAdd1() => i=13, spendTime=1016ms  
doAdd1() => i=14, spendTime=1219ms  
doAdd1() => i=15, spendTime=1422ms  
doAdd1() => i=16, spendTime=1610ms  
doAdd1() => i=17, spendTime=1813ms  
doAdd1() => i=18, spendTime=2016ms  
花费时间:12994ms  
补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,