JAVA synchronized关键字详解
2016-12-20 00:00
453 查看
#并发的问题
在java多线程编程中,我们碰到的最大的问题就是资源竞争,这令我们的正常程序流程变得复杂而诡异。
看下面这段代码:
输出: Start... Start... Start... end end end
为什么会这样呢?不同的线程进入了相同的函数体内,同时运行
就造成了线程之间的资源竞争了
#关键字synchronize
Java语言本身提供了关键字synchronize,用于对于竞争的资源加锁
synchronize标识函数与代码块.
标识函数的时候,函数为static时候为全局锁,普通时为对象锁
标识代码块的时候,括号内为使用范围
什么是对象锁呢,意思是只有相同的Test对象调用test()方法时,加锁才有用
比如:
可以看到,每个线程都是用的同一个Test类对象
此时测试结果是正常的:
Start... end Start... end Start... end
如果想要不使用同一个对象呢 ?
这时候重新修改下开始的例子,由于我是用每次都 new Test( ) 调用的
所以这里应该添加全局锁:
输出结果:
Start... end Start... end Start... end
或者不想添加为静态方法时,可以将test()方法改为:
synchronized (Test.class)
这个也是正常的, 和静态方法的作用相同了.
在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标识函数与代码块.
标识函数的时候,函数为static时候为全局锁,普通时为对象锁
public synchronized void test(); public static synchronized void test();
标识代码块的时候,括号内为使用范围
//对象锁 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"); } }
这个也是正常的, 和静态方法的作用相同了.
相关文章推荐
- java之synchronized关键字使用详解
- Java 多线程(六) synchronized关键字详解
- Java 多线程 synchronized关键字详解
- java synchronized 关键字详解
- Java 多线程(六) synchronized关键字详解
- Java synchronized关键字详解
- java synchronized关键字详解
- Java 多线程(六) synchronized关键字详解
- Java 多线程----synchronized关键字详解
- Java 多线程(六) synchronized关键字详解
- Java 多线程(六) synchronized关键字详解
- Java 多线程(六) synchronized关键字详解
- Java关键字synchronized详解
- Java 多线程(六) synchronized关键字详解
- JAVA 线程 synchronized关键字详解
- java里面的synchronized关键字详解
- Java 多线程(六) synchronized关键字详解
- Java 中的关键字 synchronized详解
- 详解java中的synchronized关键字
- Java 多线程 synchronized关键字详解