如果用synchronized修饰一个类成员方法A,那么就不会出现下面的情况:

同时多个线程访问这个类的A方法。

当然如果还有一个方法B,它没有被synchronized修饰,那么A方法与B方法是可以并行执行的。如下:

package thread;

public class SyncTest implements Runnable {

    public synchronized void m1() throws Exception{
        System.out.println("m1开始");
        Thread.sleep(2000);
        System.out.println("m1结束");
    }

    public  void m2() throws Exception {
        System.out.println("m2开始");
        Thread.sleep(2000);
        System.out.println("m2结束");
    }

    public void run() {
        try {
            m1();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        SyncTest tt = new SyncTest();
        Thread t = new Thread(tt);
        t.start();

        Thread.sleep(1000); //保证先运行m1
        tt.m2();
    }
}

大家可以先猜一下运行结果

m1先运行打印出

m1开始

然后睡觉(2s后醒来)

过了大概1s

tt.m2()运行了

打印出

m2开始

再等一会

m1结束

m2结束

运行的结果也确实是

m1开始

m2开始

m1结束

m2结束

我们得出一个结论

成员函数A使用synchronized修饰,并不会影响没有使用synchronized修饰的方法B。



不过如果给m2也加上synchronized,会怎么呢?

结果如下

m1开始

m1结束

m2开始

m2结束



恩?答案是的。即使我们m1休眠的时间再长,m2也不会在m1执行结束之前启动。

因而我们得出结论

如果一个类中多个成员函数都用synchronized修饰,那么即使在多线程下,这些函数也不能同时被调用。



上面说的所以函数都是成员函数,如果把synchronized加到static方法上呢?

大家都知道,static的方法属于类方法,它属于这个Class(注意:这里的Class不是指Class的某个具体对象),那么static获取到的锁,就是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。而非static方法获取到的锁,就是当前调用这个方法的对象的锁了。所以,他们之间不会产生互斥。

看下面的例子

/**
 * @author Jack Zhang
 * @version vb1.0
 * @Email virgoboy2004@163.com
 * @Date 2012-5-20
 */
public class Test
{
    public static synchronized void staticX() throws InterruptedException
    {
        for (int i = 0; i < 10; i++){
            Thread.sleep(1000);
            System.out.println("staticX.......................");
        }
    }

    public synchronized void x() throws InterruptedException{
        for (int i = 0; i < 10; i++){
            Thread.sleep(1000);
            System.out.println("x.......................");
        }
    }

    public static void main(String[] args)
    {
        final Test test1 = new Test();
        Thread thread = new Thread(new Runnable(){
            public void run(){
                try{
                    test1.x();
                }catch (InterruptedException e){
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }, "a");

        Thread thread1 = new Thread(new Runnable(){
            public void run(){
                try{
                    Test.staticX();
                } catch (InterruptedException e){
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }, "b");

        thread1.start();
        thread.start();
    }
}

结果是

staticX.......................

x.......................

x.......................

staticX.......................

staticX.......................

x.......................

x.......................

staticX.......................

x.......................

staticX.......................

staticX.......................

x.......................

x.......................

staticX.......................

x.......................

staticX.......................

x.......................

staticX.......................

x.......................

staticX.......................

一个锁加到的类上,另一个锁加到了对象上。是两回事。



那当我们想让所有这个类下面的对象都同步的时候,也就是让所有这个类下面的对象共用同一把锁的时候,我们如何办呢?



看代码:

/**
 * @author Jack Zhang
 * @version vb1.0
 * @Email virgoboy2004@163.com
 * @Date 2012-5-20
 */
public class Test
{
    public final static Byte[] locks = new Byte[0];

    public static void staticX() throws InterruptedException
    {
        synchronized (locks)
        {
            for (int i = 0; i < 10; i++)
            {
                Thread.sleep(1000);
                System.out.println("staticX.......................");
            }
        }
    }

    public void x() throws InterruptedException
    {
        synchronized (locks)
        {
            for (int i = 0; i < 10; i++)
            {
                Thread.sleep(1000);
                System.out.println("x.......................");
            }
        }
    }

    public static void main(String[] args)
    {
        final Test test1 = new Test();
        final Test test2 = new Test();
        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                    test1.x();
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }, "a");

        Thread thread1 = new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                    Test.staticX();
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }, "b");

        thread1.start();
        thread.start();
    }
}

结果

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

staticX.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

x.......................

关于synchronized(this)

我们知道在java中,this指的是调用这个方法的对象

如果我们写这样的锁synchronized(this) 会怎么样呢? 试一下不就知道了

public class Test
{
    public final static Byte[] locks = new Byte[0];

    public void staticX() throws InterruptedException
    {
        synchronized (this)
        {
            for (int i = 0; i < 10; i++)
            {
                Thread.sleep(1000);
                System.out.println("staticX.......................");
            }
        }
    }

    public void x() throws InterruptedException
    {
     //   synchronized (this)
        {
            for (int i = 0; i < 10; i++)
            {
                Thread.sleep(1000);
                System.out.println("x.......................");
            }
        }
    }

    public static void main(String[] args)
    {
        final Test test1 = new Test();
   //     final Test test2 = new Test();
        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                    test1.x();
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }, "a");

        Thread thread1 = new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                	test1.staticX();
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }, "b");

        thread1.start();
        thread.start();
    }
}

此时x与staticx交替打印

这个大家能理解吗?x()方法没有任何锁,它自然能执行

如果我去掉x()方法里面的

 //   synchronized (this)

这行的注释呢?

结果是先连续打印10个staticx然后再打印10个x

感谢glt

参考资料http://blog.csdn.net/virgoboy2004/article/details/7585182

关于synchronized的更多相关文章

  1. java 多线程 Synchronized方法和方法块 synchronized(this)和synchronized(object)的理解

    synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块. 1. synchronized 方法:通过在方法声明中加入 synchronized ...

  2. 单例模式中用volatile和synchronized来满足双重检查锁机制

    背景:我们在实现单例模式的时候往往会忽略掉多线程的情况,就是写的代码在单线程的情况下是没问题的,但是一碰到多个线程的时候,由于代码没写好,就会引发很多问题,而且这些问题都是很隐蔽和很难排查的. 例子1 ...

  3. Thread 学习记录 <1> -- volatile和synchronized

    恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1;  ...

  4. synchronized使用说明

    好久没有更新博客了,今天试着用简单的语言把synchronized的使用说清楚. synchronized是什么? synchronized是用来保证在多线程环境下代码同步执行的可重入的互斥锁.所谓互 ...

  5. 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition

    img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...

  6. (转)Lock和synchronized比较详解

    今天看了并发实践这本书的ReentantLock这章,感觉对ReentantLock还是不够熟悉,有许多疑问,所有在网上找了很多文章看了一下,总体说的不够详细,重点和焦点问题没有谈到,但这篇文章相当不 ...

  7. Synchronized同步性与可见性

    Synchronized是具有同步性与可见性的,那么什么是同步性与可见性呢? (1)同步性:同步性就是一个事物要么一起成功,要么一起失败,可谓是有福同享有难同当,就像A有10000去银行转5000给身 ...

  8. 基于synchronized 或 ReadWriteLock实现 简单缓存机制

    package cn.xxx.xxx; import java.util.HashMap; import java.util.Map; import java.util.concurrent.lock ...

  9. 【Java并发编程实战】-----synchronized

    在我们的实际应用当中可能经常会遇到这样一个场景:多个线程读或者.写相同的数据,访问相同的文件等等.对于这种情况如果我们不加以控制,是非常容易导致错误的.在java中,为了解决这个问题,引入临界区概念. ...

  10. Lock、ReentrantLock、synchronized、ReentrantReadWriteLock使用

    先来看一段代码,实现如下打印效果: 1 2 A 3 4 B 5 6 C 7 8 D 9 10 E 11 12 F 13 14 G 15 16 H 17 18 I 19 20 J 21 22 K 23 ...

随机推荐

  1. MySQL执行插入操作时报错1366 - Incorrect string value

    今天在测试mysql时,发现插入数据的问题,下面和大家分享下解决方法: 首先看问题原因: [Err] 1366 - Incorrect string value: '\xCF\xD6' for col ...

  2. activiti 多实例任务

    1.1.1. 前言 个人,那么当5个人都投票的时候大概分为如下几种: 1.部门所有人都去投票,当所有人都投票完成的时候,这个节点结束,流程运转到下一个节点.(所有的人都需要投票) 2.部门所有人都去投 ...

  3. 全文检索 Lucene(4)

    经过了前面几篇文章的学习,我们基本上可以适用Lucene来开发我们的站内搜索应用了.但是观察一下目前的主流的搜索引擎,我们会发现查询结果会有高亮的显示效果.所以,今天我们就来学习一下,给Lucene添 ...

  4. x264源代码简单分析:编码器主干部分-2

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  5. 如何构建Android MVVM 应用框架

    概述 说到Android MVVM,相信大家都会想到Google 2015年推出的DataBinding框架.然而两者的概念是不一样的,不能混为一谈.MVVM是一种架构模式,而DataBinding是 ...

  6. Objc中处理数组越界的一种办法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Objc的数组如果在访问时索引非法,则会抛出NSRangeEx ...

  7. 6. React 表单使用介绍

            表单是前端页面中非常重要也是非常常用的一个内容,react 也在表单方面进行了很多封装,让开发者可以方便快捷地在 react 组件中使用表单.下面介绍如何在组件中正确的使用表单,从而可 ...

  8. Dynamics CRM 2015 Online Update1 UI界面的更新变化

    听说出  Dynamics CRM 2015 Online  Update1了,立马跑去申请了个30天试用版简单的看了下,UI上的变化还是让人耳目一新的,也可能是被CRM2013的UI蹂躏太久了没 ...

  9. pig里面没有if:不能判断一个条件后决定一个执行步骤

    pig是处理流 的工具,所以数据集是流对象,处理步骤也是一样的. Pig中存在按条件处理流对象的方式有 1)filter X= FILTER A BY (f1 == 8); 2)CASE WHEN T ...

  10. Cocos2D:塔防游戏制作之旅(十)

    最终,draw方法显示这些路径点被放置在哪里,并且绘制出路径点之间的连线,它们仅仅被用作调试.一个成品游戏不应该绘制敌人的路径 - 那对于玩家来说太过容易了! 创建路径点的列表.打开HelloWorl ...