Java多线程之syncrhoized内置互斥锁的用法详解

 
 转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827547.html 
 
解决并行冲突最有效的方法就是加同步锁,主要有以下几种方法:
 
1: 动态方法同步锁:锁当前类对象。即调用该方法的类对象优先执行完毕才到下一个线程执行。
public synchronized void 方法()
{
}
实例代码:
import java.lang.Thread.State;

        import org.omg.CORBA.PUBLIC_MEMBER;

public class ThreadTest {
    public static void main(String[] args) throws Exception{
        MyRunnable m1=new MyRunnable();
        Thread t1=new Thread(m1);
        Thread t2=new Thread(m1);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(MyRunnable.num);
    }
}
class MyRunnable implements Runnable
{
    public static int num=0;
    public synchronized void add()
    {
        for(int i=0;i<100;++i)
        {
            num++;
        }
    }
    @Override
    public void run() {
        add();
    }
}

结果:200

 
2: 静态方法同步锁:锁当前类型。即: 该类型的所有类对象优先执行。凡是该类的对象且已经调用运行的,则这些类对象都是平级的,交替运行。而这 些对象对于其他类的对象则是优先的,先执行。
public static synchronized void 方法()
{
}
实例:
import java.lang.Thread.State;

        import org.omg.CORBA.PUBLIC_MEMBER;

public class ThreadTest {
    public static void main(String[] args) throws Exception{
        MyRunnable m1=new MyRunnable();
        MyRunnable m2=new MyRunnable();
        Thread t1=new Thread(m1);
        Thread t2=new Thread(m2);
        t1.start();
        t2.start();

        t1.join();
        t2.join();
        System.out.println(MyRunnable.num);
    }
}
class MyRunnable implements Runnable
{
    public static int num=0;
    public synchronized static void add()
    {
        for(int i=0;i<100;++i)
        {
            num++;
        }
    }
    @Override
    public void run() {
        add();
    }
}

结果:200

 
 
3: 代码同步锁:设置一个锁对象(绣球),用来标识谁来执行被锁的代码块。谁拿到这个对象(抢绣球),谁就执行
runnable()
{
  public Object lock=new Object();
  public void 方法()
  {
    synchronized(lock){代码块};
   }
}
 
若两个thread类对象用同一个runnable参数,则lock对象被多线程抢夺。由于lock对象的唯一性,两个线程谁拿到lock对象谁运行被锁代码块,最终结果是确定的。

 

import java.lang.Thread.State;

        import org.omg.CORBA.PUBLIC_MEMBER;

public class ThreadTest {
    public static void main(String[] args) throws Exception{
        MyRunnable m1=new MyRunnable();

        Thread t1=new Thread(m1);
        Thread t2=new Thread(m1);
        t1.start();
        t2.start();

        t1.join();
        t2.join();
        System.out.println(MyRunnable.num);
    }
}
class MyRunnable implements Runnable
{
    public static int num=0;
    public Object lock=new Object();
    public void add()
    {
        synchronized (lock) {
            for(int i=0;i<100000;++i)
            {
                num++;
            }
        }
    }
    @Override
    public void run() {
        add();
    }
}

结果:200000

 
 
若两个thread类对象不用同一个runnable对象参数,则两个线程分别对应一个lock代码块,两线程独立运行lock代码块,但交替使用CPU,会导致结果飘忽不定。
import java.lang.Thread.State;

        import org.omg.CORBA.PUBLIC_MEMBER;

public class ThreadTest {
    public static void main(String[] args) throws Exception{
        MyRunnable m1=new MyRunnable();
        MyRunnable m2=new MyRunnable();
        Thread t1=new Thread(m1);
        Thread t2=new Thread(m2);
        t1.start();
        t2.start();

        t1.join();
        t2.join();
        System.out.println(MyRunnable.num);
    }
}
class MyRunnable implements Runnable
{
    public static int num=0;
    public Object lock=new Object();
    public void add()
    {
        synchronized (lock) {
            for(int i=0;i<100000;++i)
            {
                num++;
            }
        }
    }
    @Override
    public void run() {
        add();
    }
}

 

多调试几次:结果是随机的,循环次数越大结果越随机。比如,上面for循环中如果是i<100,那么可能结果总是200,这看起来是对的,没错。原因是循环次数太少,两线程对结果影响不大。当把数字调大,如100000时,结果就很随机了,有可能是103453,112378。。。。。。。

 
 
 
 
 

转载于:https://www.cnblogs.com/ygj0930/p/5827547.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值