java多线程同步synchronized_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java多线程同步synchronized

java多线程同步synchronized

 2012/2/27 9:38:14  lyjilu  程序员俱乐部  我要评论(0)
  • 摘要:记录代码有兴趣可以运行试试,然后想想。最终结论只有一条:“synchronized”关键字同步的始终是该synchronized修饰的方法的持有对象(同步方法)该synchronized修饰的对象(同步块)目前我所知的synchronized关键字用法,分3种情况:普通方法上使用eg:publicsynchronizedvoidmethod(...){...}静态方法上使用eg:publicsynchronizedstaticvoidmethod(...){...}代码块上使用eg:...
  • 标签:多线程 Java Ron 线程

记录代码

有兴趣可以运行试试,然后想想。

最终结论只有一条:

“synchronized”关键字同步的始终是

该synchronized修饰的方法的持有对象(同步方法)

该synchronized修饰的对象(同步块)

目前我所知的synchronized关键字用法,分3种情况:

?

  1. 普通方法上使用??eg: public?synchronized void method(...){...}
  2. 静态方法上使用 eg: public? synchronized static void method(...){...}
  3. 代码块上使用 eg:....synchronized (obj) {...}
先看下第一种:
/**
 * 关于同步关键字 “synchronized” 的学习,思考
 */
package sync;

import java.util.ArrayList;
import java.util.List;

/**
 * @author lyjilu   2012-2-26
 * @version 1.0
 * Copyright (c) 2011-2012, lyjilu. All rights reserved.
 */
public class First implements Sync{
	static List<String> list = new ArrayList<String>();
	/**
	 * 如果不注意编码规范。
	 * 此方法里做的操作真的是同步,安全的吗?
	 * 看看几种情况下,list的值.
	 * @throws InterruptedException
	 */
	public synchronized void a() throws InterruptedException {
		System.out.println(System.currentTimeMillis() + "我是A开始=====");
		list.add("a1");
		Thread.sleep(1000);
		System.out.println(list);
		list.add("a2");
		System.out.println(System.currentTimeMillis() + "我是A结束=====");
	}
	
	public synchronized void b() throws InterruptedException {
		System.out.println(System.currentTimeMillis() + "我是A开始=====");
		list.add("a1");
		Thread.sleep(1000);
		System.out.println(list);
		list.add("a2");
		System.out.println(System.currentTimeMillis() + "我是A结束=====");
	}
	/**
	 * 
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException {
		//第一种情况:不同对象访问那个同步方法
//		First.t1();
		//第二种情况:同一对象访问那个同步方法
//		First.t2();
		//第三种情况:同一对象访问该对象不同同步方法
		First.t3();
	}
	/**
	 * 不同对象访问那个同步方法
	 * @throws InterruptedException
	 */
	public static void t1() throws InterruptedException{
		First f1 = new First();
		First f2 = new First();
		FirstT1 tt = new FirstT1(f1);
		FirstT2 tt2 = new FirstT2(f2);
		new Thread(tt).start();
		Thread.sleep(100);
		new Thread(tt2).start();
	}
	/**
	 * 同一对象访问那个同步方法
	 * @throws InterruptedException
	 */
	public static void t2() throws InterruptedException{
		First f1 = new First();
		FirstT1 tt = new FirstT1(f1);
		FirstT2 tt2 = new FirstT2(f1);
		new Thread(tt).start();
		Thread.sleep(100);
		new Thread(tt2).start();
	}
	/**
	 * 同一对象访问该对象的不同同步方法
	 * @throws InterruptedException
	 */
	public static void t3() throws InterruptedException{
		First f1 = new First();
		FirstT1 tt = new FirstT1(f1);
		FirstT3 tt3 = new FirstT3(f1);
		new Thread(tt).start();
		Thread.sleep(100);
		new Thread(tt3).start();
	}
}

class FirstT1 implements Runnable {
	First t;
	public FirstT1(First test) {
		t = test;
	}
	public void run() {
		try {
			t.a();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class FirstT2 implements Runnable {
	First t;
	public FirstT2(First test) {
		t = test;
	}
	public void run() {
		try {
			t.a();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
class FirstT3 implements Runnable {
	First t;
	public FirstT3(First test) {
		t = test;
	}
	public void run() {
		try {
			t.b();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
? 第二种情况:
/**
 * 关于同步关键字 “synchronized” 的学习,思考
 */
package sync;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author lyjilu   2012-2-26
 * @version 1.0
 * Copyright (c) 2011-2012, lyjilu. All rights reserved.
 */
public class Second implements Sync{
	static List<String> list = new ArrayList<String>();
	public synchronized static void a() throws InterruptedException {
		System.out.println(System.currentTimeMillis() + "我是A开始=====");
		list.add("a1");
		Thread.sleep(1000);
		System.out.println(list);
		list.add("a2");
		System.out.println(System.currentTimeMillis() + "我是A结束=====");
	}
	public synchronized static void b() throws InterruptedException {
		System.out.println(System.currentTimeMillis() + "我是B开始=====");
		list.add("a1");
		Thread.sleep(1000);
		System.out.println(list);
		list.add("a2");
		System.out.println(System.currentTimeMillis() + "我是B结束=====");
	}
	/**
	 * synchronized同步的是持有该方法的对象,这里是Second.class
	 * 所以,不管如何调用,方法a、b总是同步的,
	 * 并且,Second.class被同步使用的时候,是无法通过Second调用其它同步方法的,
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException {
		SecondT1 tt = new SecondT1();
		SecondT2 tt2 = new SecondT2();
		new Thread(tt).start();
		new Thread(tt2).start();
	}
}

class SecondT1 implements Runnable {
	public void run() {
		try {
			Second.a();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class SecondT2 implements Runnable {
	public void run() {
		try {
			Second.b();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
?第三种情况:
/*
 * Third.java
 * @author lyjilu   2012-2-26
 * @version 1.0
 * Copyright (c) 2011-2012, lyjilu. All rights reserved.
 */
package sync;

import java.util.ArrayList;
import java.util.List;

/**
 * @author lyjilu 2012-2-26
 * @version 1.0 Copyright (c) 2011-2012, lyjilu. All rights reserved.
 */
public class Third implements Sync {
	/**
	 * 把list换成 static的,会怎样
	 */
	static List<String> list = new ArrayList<String>();

	public void a() throws InterruptedException {
		System.out.println("进入方法a");
		synchronized (list) {
			list.add("a1");
			Thread.sleep(1000);
			System.out.println(list);
			list.add("a2");
		}
		System.out.println("离开方法a");
	}

	public void b() throws InterruptedException {
		System.out.println("进入方法a");
		synchronized (list) {
			list.add("a1");
			Thread.sleep(1000);
			System.out.println(list);
			list.add("a2");
		}
		System.out.println("离开方法a");
	}

	/**
	 * 如果list非静态,那么list是和实例对象绑定的,也就是说每new一个Third对象,
	 * 那么list就是这个new的对象的属性,所以不同的new对象
	 * ,是可以同时访问同一方法,并且访问同一块的,只要不在同步块里操作公共对象,那么也不存在同步问题
	 * 如果list是静态的,那么list是和Third.class绑定的,所以,即使是多个新实例的对象,也不能同时对list进行操作,因为list是相对Third.class,是绝对同步的
	 * @param args
	 */
	public static void main(String[] args) {
		// 情况一:同一对象,调用有同步块的方法
		 Third.t1();
		// 情况二:不同对象,调用有同步块的方法
		 Third.t2();
		// 情况三:同一对象,调用有同步块的不同方法
		 Third.t3();
		// 情况四:不同对象,调用有同步块的不同方法
		 Third.t4();
	}

	public static void t1() {
		Third t1 = new Third();
		ThirdT1 tt1 = new ThirdT1(t1);
		ThirdT2 tt2 = new ThirdT2(t1);
		new Thread(tt1).start();
		new Thread(tt2).start();
	}

	public static void t2() {
		Third t1 = new Third();
		Third t2 = new Third();
		ThirdT1 tt1 = new ThirdT1(t1);
		ThirdT2 tt2 = new ThirdT2(t2);
		new Thread(tt1).start();
		new Thread(tt2).start();
	}

	public static void t3() {
		Third t1 = new Third();
		ThirdT1 tt1 = new ThirdT1(t1);
		ThirdT3 tt2 = new ThirdT3(t1);
		new Thread(tt1).start();
		new Thread(tt2).start();
	}

	public static void t4() {
		Third t1 = new Third();
		Third t2 = new Third();
		ThirdT1 tt1 = new ThirdT1(t1);
		ThirdT3 tt2 = new ThirdT3(t2);
		new Thread(tt1).start();
		new Thread(tt2).start();
	}
}

class ThirdT1 implements Runnable {
	Third t;

	public ThirdT1(Third test) {
		t = test;
	}

	public void run() {
		try {
			t.a();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class ThirdT2 implements Runnable {
	Third t;

	public ThirdT2(Third test) {
		t = test;
	}

	public void run() {
		try {
			t.a();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class ThirdT3 implements Runnable {
	Third t;

	public ThirdT3(Third test) {
		t = test;
	}

	public void run() {
		try {
			t.b();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
? 如果遇见多线程同步问题, 最主要是判断synchronized修饰的方法属于哪个对象(包括静态)或synchronized修饰的对象(同步块)。 如有什么错误,还劳烦指出!
发表评论
用户名: 匿名