zoukankan      html  css  js  c++  java
  • 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。。。。。。。

     
     
     
     
     
  • 相关阅读:
    SPRINGMVC整合SOLR
    solr 嵌套entity 高亮查询
    solr 高级进阶,解决问题
    Solr的主从模式Master-Slave
    Solr8.0速成系列 | Solr客户端常用操作和查询语法 08
    solr 的全量更新与增量更新
    solr8.0.0和tomcat8.5.40的整合,完整版
    设置 Tomcat 的JVM运行内存
    mongo主库地址变更,从库修改数据源IP
    mysql数据表如何导入MSSQL中
  • 原文地址:https://www.cnblogs.com/ygj0930/p/5827547.html
Copyright © 2011-2022 走看看