Java多线程同步Synchronized使用分析
由于servlet 是多线程单例的。
struts1 的前端控制器是单例的,线程不安全的;每次请求都会用同一actionServlet;
struts2 的action不是单例的,线程安全的;每次请求都会新new一个action来接收;
因此如果使用 servlet 或者strtus1 线程安全问题,不能不考虑,下面内容。
同步的概念:
同步分为 同步方法 和 同步块 两种方式。
锁定的内容分为 锁定类定实例 和 锁定类对象 两种方式。
变量分为 实例变量(不带static的变量) 和 类变量(带static的变量)
变量分为 属性 和 方法
使用同步的原因
1. 在系统中对访类要使用多线程进行访问;
2. 在该类中有 类变量, 或者是 在类的方法中有访问 公共资源(如一个外部文件的读写)。
同步锁锁定的内容是什么?
无论你将Synchronized加在方法前还是加在一个变量前,其锁定的都是一个 类对象。 每一个对象都只有一个锁与之相关联。
下例中分情况的列举各种情况下的同步效果
1. Synchronized 加在方法上, (同步方法,锁定类实例)
public class Demo1 { public synchronized void m1(){ //............... } public void m2(){ //............ synchronized(this){ //......... } //........ }}
public class Demo2 { Object a = new Object(); Object b = new Object(); public void m1(){ //............ synchronized(a){ //......... } //........ } public void m2(){ //............ synchronized(b){ //......... } //........ }}
public class Demo3 { static Object o = new Object(); public static synchronized void m1() { //.... } public static void m2() { //... synchronized (Demo3.class) { //..... } //..... } public static void m3() { //.......... try { synchronized (Class.forName("Demo3")) { //............ } } catch (ClassNotFoundException ex) { } //............. } public static void m4() { //............ synchronized(o){ //........ } //.......... }}以上4个方法中实现的效果都是一样的,其锁定的对象都是类Demo3,而不是类实例对象 ,即在多线程中,其共享的资源是属于类的,而不是属于类对象的。在这种情况下,如果thread1 访问了这4个方法中的任何一个, 在同一时间内其它的线程都不能访问 这4个方法。
public class Demo4 { static String path = "file path"; public void readConfiFile() { synchronized (path) { // 读取该path指定的文件。 } } public void writeConfiFile() { synchronized (path) { //写信息到该path指定的文件。 } }}