• Java:多线程<二> 同步


          由于多线程的访问出现延迟和线程的随机性,在使用多线程时往往会伴随安全性的问题,这些问题一旦出现将会是非常严重的。为了解决这种安全性问题,synchronized出现了。

           synchronized用法一,放在方法内,必须传一个对象obj

    synchronized(obj)
    {
        //需要被同步的代码
    }

            synchronized用法二,放在方法上,不需要传对象

    public synchronized void method()
    {
        //该方法体中所有的代码都被同步了
    }

    例子:银行有个小金库,初始为0,有一天有两个富商来存金币,每人每次同时存100金币,没有使用同步的多线程代码

    class Bank
    {
        private int gold=0;
        public void add(int num)
        {
            try
            {
                Thread.sleep(10);
                gold += num;
            }
            catch (Exception e)
            {
                System.out.println("银行内部错误,暂停服务!");
                System.exit(0);
            }
            System.out.println("金库里有"+gold+"金币");
        }
    }
    
    class Business implements Runnable
    {
        private Bank b = new Bank();
        public void run()
        {
            for(int i=0;i<3;i++)
            {
                b.add(100);
            }
        }
    }
    
    class StoreGold
    {
        public static void main(String[] args) 
        {
            Business b = new Business();
    
            Thread t1 = new Thread(b,"张三");
            Thread t2 = new Thread(b,"李四");
            t1.start();
            t2.start();
        }
    }

            运行时,就有可能出现金库里有500金币两次等等错误情况,其原因是gold没有被同步,有被同时使用一个值的情况。在Bank的add方法中应该加上同步,如下

    class Bank
    {
        private int gold=0;
        public void add(int num)
        {
            synchronized(this)
            {
                try
                {
                    Thread.sleep(10);
                    gold += num;
                }
                catch (Exception e)
                {
                    System.out.println("银行内部错误,暂停服务!");
                    System.exit(0);
                }
            }        
            System.out.println("金库里有"+gold+"金币");
        }
    }

             也可以把synchronized加在方法上,这样的写法边简单了,但是同步的内容就多了。同步函数的锁是this。

    class Bank
    {
        private int gold=0;
        public synchronized void add(int num)
        {
            try
            {
                Thread.sleep(10);
                gold += num;
            }
            catch (Exception e)
            {
                System.out.println("银行内部错误,暂停服务!");
                System.exit(0);
            }    
            System.out.println("金库里有"+gold+"金币");
        }
    }

          虽然同步可以让线程在处理某些事务时更为安全,但同时由于每个线程都多了拿锁、等待、释放锁等操作,所以会影响程序运行的速率。

    那么什么代码需要被同步呢?

    1,明确哪些代码是多线程运行代码

    2,明确共享数据

    3,明确多线程运行代码中哪些语句是操作共享数据的

    同步使用的是什么锁呢?

    1,函数使用的锁是this

    2,静态函数使用的锁是类名.class,字节码文件对象

  • 相关阅读:
    在线程中使用OpenFileDialog
    Log4net附加
    SQL表间列根据条件复制(赋值)
    DataGridView使用
    Latex使用总结及备忘
    Windows获取文件状态
    TabControl取消首次定位焦点
    C#跨线程调用
    电子词典的查寻程序,发送和接收应答程序
    电子词典的相关子函数db.c程序
  • 原文地址:https://www.cnblogs.com/siyingcheng/p/4314587.html
Copyright © 2020-2023  润新知