`
leidiqiu
  • 浏览: 135068 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java 关于线程同步的问题

    博客分类:
  • JAVA
阅读更多

      Java 线程同步问题也不是什么新鲜问题了,这里做一个总结吧。

 

 

      线程同步时,调用一个 synchronized 的方法,所有的 synchronized 的方法都被锁定,其他的方法不受影响。

 

看一个例子:

 

package com.ldq;

public class Test06 {

	private static Obj o1;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		o1 = new Obj();

		new Thread() {
			public void run() {
				o1.method01();
			}
		}.start();

		new Thread() {
			public void run() {
				o1.method02();
			}
		}.start();

		new Thread() {
			public void run() {
				o1.method03();
			}
		}.start();

	}
}

class Obj {

	synchronized void method01() {
		while (true) {
			System.out.println("method01");
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	void method02() {
		while (true) {
			System.out.println("method02");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	synchronized void method03() {
		while (true) {
			System.out.println("method03");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

 

 

以上代码输出结果为:

method01
method02
method02
method02
method02
method02
method01
method02
method02
method02

 

      分析:首先生成一个对象 o1 ,它有 3 个方法,其中 method01 和 method03 有关键字 synchronized 修饰,说明这两个方法要做线程同步,而 method02 没有关键字 synchronized 修饰,说明不用做同步。可见,对象加锁操作是针对有 synchronized 关键字而言的。调用 synchronized 的方法,整个对象的所有 synchronized 的方法都被加锁,但是其他的方法不受影响。

 

 

      sleep() 和 wait() 的区别

 

      sleep() 是 Thread 类的方法,wait() 是 Object 类的方法,由于所有类都是 Object 的子类,因此所有类都有 wait() 方法,从源代码看 public final native void wait() ,wait() 方法是 final ,不允许重载或是覆盖的,并且是 native ,是由本机接口实现的,与 JVM 的相关。

 

      sleep() 就是让线程空转,但是仍然占用资源。wait() 用在 synchronized 修饰的方法里,让线程暂停,并释放资源,直到有别的线程调用 notify() 或者 notifyAll() 方法唤醒。

 

      对某一个对象,wait() 让线程进入等待池,notify() 唤醒一个线程,notifyAll() 唤醒所有的线程。

 

看代码吧:

 

 

package com.ldq;

public class Test07 {

	private static MyObj o1;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		o1 = new MyObj();

		new Thread() {
			public void run() {
				o1.method01();
			}
		}.start();

		new Thread() {
			public void run() {
				o1.method02();
			}
		}.start();

	}
}

class MyObj {

	synchronized void method01() {
		while (true) {

			System.out.println("method01");

			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			notify();

			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	synchronized void method02() {
		while (true) {

			System.out.println("method02");

			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			notify();

			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

 

 

 

输出为:

method01
method02
method01
method02
method01
method02

...

 

 

      分析:匿名线程1执行完method01后,notify() 等待的线程,wait() 释放锁,匿名线程2获得锁后输出,notify() 等待的匿名线程1,自己 wait() 释放锁,此时,匿名线程1就可以继续执行,如此循环 ...

 

 

分享到:
评论
6 楼 scholers 2011-01-15  
1、synchronized关键字的作用域有二种:
1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。

2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;

3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;
5 楼 lx_corn 2011-01-14  
线程同步时,调用一个 synchronized 的方法,所有的 synchronized 的方法都被锁定,其他的方法不受影响。
  果然 问题都是这句引起的。。
4 楼 zhangyou1010 2011-01-14  
“ 线程同步时,调用一个 synchronized 的方法,所有的 synchronized 的方法都被锁定,其他的方法不受影响。”

要看你怎么用synchronized吧?
3 楼 buptwhisper 2011-01-14  
楼主是不是有点错误?
"线程同步时,调用一个 synchronized 的方法,所有的 synchronized 的方法都被锁定,其他的方法不受影响。"我认为是不正确的。
synchronized 锁的是当前对象实例,跟其它的synchronized 方法是没有任何冲突与联系的。楼主的例子中之所以出现这样的情况,是因为你用的是同一个实例罢了。当你在调用某个synchronized 时,首先去取得对应对象的锁,如果没有被使用,则执行该方法;而如果已经被使用,则等待;特别地,如果你synchronized 的是static方法,锁的是对应的Class对象。
2 楼 神之小丑 2011-01-14  
单实例多线程notify 和notifyAll唤醒的是此实例上的等待的线程
1 楼 yousteely 2011-01-13  
分享成果是一种美德

相关推荐

    Java多线程同步.pdf

    因此,在使用Java多线程同步机制时,需要小心避免这些问题的出现。 Java多线程同步机制在实际应用中的应用 Java多线程同步机制在实际应用中有很多应用,例如: * 在线银行系统中,使用Java多线程同步机制来确保...

    java多线程同步问题

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

    JAVA实现线程间同步与互斥生产者消费者问题

    在Java编程中,线程同步和互斥是多线程编程中的重要概念,它们用于解决多个线程同时访问共享资源时可能出现的问题。本项目通过一个生产者消费者问题的实例,展示了如何在Java中实现线程间的同步与互斥。 生产者消费...

    java多线程同步例子

    java多线程同步互斥访问实例,对于初学者或是温故而知新的同道中人都是一个很好的学习资料

    java 线程同步 信号量控制同步

    Java 线程同步控制机制 线程同步是 Java 编程中的一种机制,用于控制多个线程之间的资源访问顺序,以避免线程之间的冲突和数据不一致。线程同步的目的就是避免线程“同步”执行,即让多个线程之间排队操作共享资源...

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

    本文通过对Java多线程同步机制的研究和分析,旨在解决多线程中的同步问题和共享资源的访问保护问题。 一、Java多线程同步机制的重要性 Java多线程同步机制是Java编程语言中的一种机制,它允许多个线程同时执行,...

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

    本文主要研究了基于Java多线程同步的安全性问题,讨论了Java多线程同步机制的实现方法和安全性问题的解决方法。文章首先介绍了Java多线程同步的必要性和重要性,然后讨论了Java多线程同步机制的实现方法,包括使用...

    java 多线程同步

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

    JAVA 线程实现数据库的主从同步更新

    在Java编程环境中,...总之,使用Java线程实现数据库主从同步更新是一种常见且实用的技术手段,它涉及到多线程编程、数据库操作、事务管理等多个方面。理解和掌握这些知识点对于开发高可用性的分布式系统至关重要。

    java synchronize 线程同步

    Java中的`synchronized`关键字是用于实现线程同步的关键机制,主要目的是解决多线程环境下的数据安全问题。当多个线程访问共享资源时,如果没有适当的同步控制,可能会导致数据不一致或者竞态条件等问题。线程同步...

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

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

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

    Java多线程同步是编程中一个非常重要的概念,特别是在并发编程和高并发系统设计中起到关键作用。在Java中,为了保证线程安全,避免数据竞争和不一致的状态,我们通常会使用同步机制来控制对共享资源的访问。本文将...

    java 多线程同步方法的实例

    在Java编程语言中,多线程同步是一种控制多个线程并发执行的重要机制,它确保了共享资源的安全访问,防止数据不一致性和竞态条件的发生。本文将深入探讨Java中的多线程同步方法,并通过实例来阐述其工作原理。 首先...

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

    在实际应用中,Java多线程同步机制可以用于解决多种问题,例如售票系统、银行系统等。通过使用同步机制,可以避免多线程之间的冲突和错误,提高系统的安全性和可靠性。 多线程编程的优点是可以提高系统的性能和效率...

    Java多线程同步问题的探究.pdf

    在探究Java多线程同步问题时,需要关注的关键知识点包括synchronized关键字的使用、JDK 5引入的java.util.concurrent.locks包下的锁机制、以及JDK 1.2中ThreadLocal类的使用。此外,了解JVM(Java虚拟机)在处理多...

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

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

    Java多线程和同步

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

    java多线程代码案例(创建线程,主线程,线程优先级,线程组,线程同步,线程间的通信)

    线程同步是为了防止多个线程同时访问共享资源导致的数据不一致问题。Java提供了多种同步机制,包括`synchronized`关键字、`wait()`, `notify()`, `notifyAll()`方法、`Lock`接口(如`ReentrantLock`)以及`...

Global site tag (gtag.js) - Google Analytics