JAVA synchronized关键字详解

#并发的问题 在java多线程编程中,我们碰到的最大的问题就是资源竞争,这令我们的正常程序流程变得复杂而诡异。

看下面这段代码:

class Test {
    public void test() {
            System.out.println("Start...");
            sleep(100);
            System.out.println("end");
    }
}

public class main {
    public static void main(String[] argv) {
        for(int i=0;i<3;i++)
            new Thread( ()-> new Test().test()) .start();
    }
}

输出: Start... Start... Start... end end end

为什么会这样呢?不同的线程进入了相同的函数体内,同时运行
就造成了线程之间的资源竞争了
#关键字synchronize Java语言本身提供了关键字synchronize,用于对于竞争的资源加锁 synchronize标识函数与代码块.

  1. 标识函数的时候,函数为static时候为全局锁,普通时为对象锁
public synchronized void test();  
public static synchronized void test();
  1. 标识代码块的时候,括号内为使用范围
//对象锁
public void test() {
        synchronized(this){
        }
}
//全局锁
public void test() {
        synchronized(Test.class){
        }
}

什么是对象锁呢,意思是只有相同的Test对象调用test()方法时,加锁才有用
比如:

// synchronized(this) 锁只能锁住当前的this对象
// 也就是由同一个Test类生成的实例对象 调用test()时才会生效
// 但是由不同的对象调用代码时,是无效的
//
// 如果真的想使用全局的锁效果
// 1:方法加入static,静态方法是没有this的,所以默认则是整个类的对象
// 2:synchronized( Test.class )  这样锁住的就是整个类的对象了
//
class Test {
    public synchronized void test() {
        System.out.println("Start...");
        sleep();
        System.out.println("end");
    }
}

public class main {
    public static void main(String[] argv) {
        Test t = new Test();
        for(int i=0;i<3;i++)
            new Thread( () -> t.test()) .start();
    }
}

可以看到,每个线程都是用的同一个Test类对象 此时测试结果是正常的:

Start... end Start... end Start... end

如果想要不使用同一个对象呢 ?
这时候重新修改下开始的例子,由于我是用每次都 new Test( ) 调用的
所以这里应该添加全局锁:

class Test {
    public static synchronized void test() {
            System.out.println("Start...");
            Test.sleep();
            System.out.println("end");
    }
}

输出结果:

Start... end Start... end Start... end

或者不想添加为静态方法时,可以将test()方法改为: synchronized (Test.class)

public void test() {
      synchronized (Test.class){
            System.out.println("Start...");
            sleep();
            System.out.println("end");
      }
}

这个也是正常的, 和静态方法的作用相同了.

转载于:https://my.oschina.net/tasker/blog/808869

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值