锁的范围越小,对代码执行效率的影响最小。最好的方式就是不加锁,并发编程不一定都是非线程安全的,只有多线程共享同一实例变量才有可能会出现线程安全问题。非线程安全问题才需要加锁进行同步。
1、synchronized 方法
解决了线程安全的问题,但影响执行效率;synchronized 方法 锁的范围是最大的,所以执行效率也是最慢的。
synchronized public void printA() { try { System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printA"); Thread.sleep(3000); System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printA"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
2、synchronized static 方法
每一个 *.java 文件对应class类的实例在内存中是单例的。synchronized static 方法 是对 *.java 文件对应的Class类对象进行持锁;synchronized 方法 是将方法所在类的实例对象为锁,俩者是俩把不同的锁。
synchronized static void printC() { try { System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printC"); System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printC"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
3、synchronized(xxx.class)代码块:
synchronized(xxx.class)代码块可以对类的所有对象实例起作用。
public void printC() { synchronized (Service1.class) { System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printC"); System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开printC"); } }
4、synchronized(this)代码块:
锁定的是当前对象,对比 synchronized 方法,减少了锁的范围,也就是减少了同步代码的范围,从而提高了程序执行效率。
public void println(String x) { synchronized (this) { print(x); newline(); } }
5、synchronized (非this对象)代码块:
优点是存在俩把锁,不与其他 synchronized(this)争抢 this 锁,减少同步的范围,大大提高运行效率。
package com.yu.syn; public class Service2 { private String usernameParam; private String passwordParam; private String anything = new String(); public void setUsernamePassword(String username, String password) { String anything = new String(); try { synchronized (anything) { System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入同步快"); usernameParam = username; Thread.sleep(3000); passwordParam = password; System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开同步快"); } } catch (InterruptedException e) { e.printStackTrace(); } } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)