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,字节码文件对象

原文地址:https://www.cnblogs.com/siyingcheng/p/4314587.html