`
lyjilu
  • 浏览: 175692 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

java多线程同步synchronized

    博客分类:
  • java
阅读更多

记录代码

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

最终结论只有一条:

“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修饰的对象(同步块)。
如有什么错误,还劳烦指出!
0
0
分享到:
评论
3 楼 zqb666kkk 2014-10-29  
lyjilu 写道
zqb666kkk 写道
第一种和第三种的区别?

第一种同步的是是当前对象 this,
第三种是 ()里面的对象

性能上有什么区别 或者说还有其他什么区别  或者说什么情况下用第一种 什么情况下用第三种?
2 楼 lyjilu 2014-10-28  
zqb666kkk 写道
第一种和第三种的区别?

第一种同步的是是当前对象 this,
第三种是 ()里面的对象
1 楼 zqb666kkk 2014-10-27  
第一种和第三种的区别?

相关推荐

    浅析Java多线程同步synchronized

    Java多线程同步synchronized Java多线程同步synchronized是Java编程语言中最基本的同步机制之一。它通过锁机制来实现多线程之间的同步,确保多个线程访问共享资源时的安全性。 在Java中,synchronized关键字可以...

    Java多线程同步.pdf

    Java多线程同步是指在Java语言中,如何使用synchronized关键字和其他同步机制来确保多线程程序的正确执行。在Java语言中,synchronized关键字用于对方法或者代码块进行同步,但是仅仅使用synchronized关键字还不能...

    Java多线程同步Synchronized深入解析

     1、在系统中对访类要使用多线程进行访问;  2、在该类中有 类变量,或者是 在类的方法中有访问公共资源(如一个外部文件的读写)。  同步锁锁定的内容是什么?  无论你将Synchronized加在方法前还是加在...

    Java多线程同步机制研究分析.pdf

    Java多线程同步机制有两种类型:synchronized方法和synchronized块。synchronized方法是将访问共享资源的方法标记为synchronized,然后该标记的方法来控制对类成员变量的访问。synchronized块是将程序的某段代码使用...

    基于Java多线程同步的安全性研究.pdf

    文章首先介绍了Java多线程同步的必要性和重要性,然后讨论了Java多线程同步机制的实现方法,包括使用synchronized关键字和Java.util.concurrent.locks包中的Lock对象。接着,文章讨论了Java多线程同步机制中可能出现...

    Java多线程同步机制的应用分析.pdf

    "Java多线程同步机制的应用分析" Java多线程同步机制的应用分析是指在Java语言中,如何使用同步机制来保护临界区,以避免多线程之间的冲突和错误。该机制通过管程机制和同步语法来保护临界区,使得多线程可以安全...

    java的线程同步机制synchronized关键字的理解_.docx

    Java 线程同步机制中 synchronized 关键字的理解 Java 的线程同步机制是为了解决多个线程共享同一片存储空间所带来的访问冲突问题。其中,synchronized 关键字是 Java 语言中解决这种冲突的重要机制。 ...

    java 多线程同步

    Java多线程同步是Java编程中关键的并发概念,它涉及到如何在多个线程访问共享资源时保持数据的一致性和完整性。`java.util.concurrent`包是Java提供的一个强大的并发工具库,它为开发者提供了多种线程安全的工具,...

    Java多线程(Synchronized+Volatile+JUC 并发工具原理+线程状态+CAS+线程池)

    Java 多线程(Synchronized+Volatile+JUC 并发工具原理+线程状态+CAS+线程池) Java 多线程是 Java 语言中的一种并发编程机制,允许程序同时执行多个线程,以提高程序的执行效率和响应速度。 Java 多线程机制提供了...

    基于Java多线程同步技术的简易模拟售票系统实现.pdf

    根据给定文件的信息,本篇文档是关于Java多线程同步技术在简易模拟售票系统中的应用研究。文档详细介绍了多线程的概念、如何在Java中创建线程、线程同步技术以及如何利用这些技术来解决共享资源访问时的数据一致性...

    java 多线程synchronized互斥锁demo

    标题中的"java 多线程synchronized互斥锁demo"指的是一个示例,展示了如何在多线程环境下使用`synchronized`关键字创建互斥锁,确保同一时间只有一个线程可以访问特定的代码块或方法。 描述中的"一个多线程访问的同...

    Java多线程同步具体实例讲解 .doc

    总结起来,Java多线程同步是通过`synchronized`关键字实现的,它可以应用于方法或代码块,保证同一时刻只有一个线程能够执行特定的代码。通过合理使用同步机制,开发者可以有效地管理并发程序中的资源访问,避免数据...

    java多线程同步问题

    多线程注意:wait()方法的调用要有判定条件常用 while () obj.wait(timeout, nanos); ... // Perform action appropriate to condition } synchronized会影响共享数据,但对其他语句的执行不会有规律了!

    java 多线程同步方法的实例

    在Java编程语言中,多...同时,理解并掌握这些同步机制的原理和使用场景,对于提升Java多线程编程的能力至关重要。在实际开发中,要特别注意死锁、活锁和饥饿等问题,避免因线程同步不当而导致的性能下降或程序错误。

    Java多线程同步具体实例.doc

    Java多线程同步是编程中一个非常重要的概念,特别是在并发编程中,用于解决多个线程访问共享资源时可能引发的数据不一致问题。本实例通过一个简单的火车票售票系统来演示同步机制的应用。 在这个实例中,我们创建了...

    Java多线程和同步

    Java线程(二):线程同步synchronized和volatile 详细讲解Java 同步的原理技术资料

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    java同步synchronized关键字用法示例

    Java中的`synchronized`...总之,`synchronized`关键字在Java多线程编程中扮演着关键角色,确保了共享资源的安全访问,避免了竞态条件和数据不一致。理解和熟练运用`synchronized`对于编写健壮的并发程序至关重要。

Global site tag (gtag.js) - Google Analytics