`

Java线程之线程的同步与锁

阅读更多

一、同步问题提出

线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。

二、同步和锁定

Java中每个对象都有一个内置锁。

当线程运行到非静态的synchronized同步方法上时,自动获得与正在执行代码的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁,锁定对象、在对象上锁或在对象上同步。

当程序运行到synchronized同步方法货代码块时才该对象锁才起作用。

一个对象只有一个锁。所以如果一个线程获得该锁,就没有其他线程可以获得锁,知道第一个线程释放(或返回)锁。这也意味着任何其他线程不能进入该对象上synchronized方法或者代码块,知道该锁被释放。

释放锁是指锁线程退出了synchronized同步方法或代码块。

有关锁和同步:

a、只能同步方法、不能同步变量和类;

b、每个对象只有一个锁;当提到同步时,应该清楚在什么上同步?也就是说,在哪个对象上同步?

c、不必同步类中所有方法,类可以同时拥有同步和非同步方法。

d、如果两个线程要执行一个类中的synchronized方法,并且两个线程使用相同的实例来调用方法,那么一次只能有一个线程能够执行方法,另一个需要等待,直到锁被释放。也就是说:如果一个线程在对象上获得一个锁,就没有任何其他线程可以进入(该对象的)类中的任何一个同步方法。

e、如果线程拥有同步和非同步方法,则非同步方法可以被多个线程自由访问而不受锁的限制。

f、线程睡眠时、它所持的任何锁都不会释放。

g、线程可以获得多个锁。比如,在一个对象的同步方法里面调用另外一个对象的同步方法,则获取了两个对象的同步锁。

h、同步损害并发性,应该尽力可能缩小同步范围。同步不但可以同步整个方法,还可以同步方法中一部分代码块。

i、在使用同步代码块时候,应该指定在哪里个对象上同步,也就是说要获取那个对象的锁。


三、静态方法同步

要同步静态方法,需要一个用于整个类对象的锁,这个对象是就是这个类(XXX.class)

        public static synchronized void setName(String name) {
		XXX.name = name;
	}

	public static void setName_(String name) {
		synchronized (XXX.class) {
			XXX.name = name;
		}
	}
 四、如果线程不能不能获得锁会怎么样

如果线程试图进入同步方法,而其锁已经被占用,则线程在该对象上被阻塞。实质上,线程进入该对象的的一种池中,必须在哪里等待,直到其锁被释放,该线程再次变为可运行或运行为止。

当考虑阻塞时,一定要注意哪个对象正被用于锁定:

1、调用同一个对象中非静态同步方法的线程将彼此阻塞。如果是不同对象,则每个线程有自己的对象的锁,线程间彼此互不干预。

2、调用同一个类中的静态同步方法的线程将彼此阻塞,它们都是锁定在相同的Class对象上。

3、静态同步方法和非静态同步方法将永远不会彼此阻塞,因为静态方法锁定在Class对象上,非静态方法锁定在该类的对象上。

4、对于同步代码块,要看清楚什么对象已经用于锁定(synchronized后面括号的内容)。在同一个对象上进行同步的线程将彼此阻塞,在不同对象上锁定的线程将永远不会彼此阻塞。

五、何时需要同步

在多个线程同时访问互斥(可交换)数据时,应该同步以保护数据,确保两个线程不会同时修改更改它。

对于非静态字段中可更改的数据,通常使用非静态方法访问。

对于静态字段中可更改的数据,通常使用静态方法访问。

如果需要在非静态方法中使用静态字段,或者在静态字段中调用非静态方法,问题将变得非常复杂。已经超出SJCP考试范围了。

六、线程安全类

当一个类已经很好的同步以保护它的数据时,这个类就称为“线程安全的”。

即使是线程安全类,也应该特别小心,因为操作的线程之间仍然不一定安全。

举个形象的例子,比如一个集合是线程安全的,有两个线程在操作同一个集合对象,当第一个线程查询集合非空后,删除集合中所有元素的时候。第二个线程也来执行与第一个线程相同的操作,也许在第一个线程查询后,第二个线程也查询出集合非空,但是当第一个执行清除后,第二个再执行删除显然是不对的,因为此时集合已经为空了。

七、线程死锁

死锁对Java程序来说,是很复杂的,也很难发现问题。当两个线程被阻塞,每个线程在等待另一个线程时就发生死锁。

八、线程同步小结

1、线程同步的目的是为了保护多个线程反问一个资源时对资源的破坏。

2、线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他同步方法。

3、对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁,当在一个同步方法中访问另外对象上的同步方法时,会获取这两个对象锁。

4、对于同步,要时刻清醒在哪个对象上同步,这是关键。

5、编写线程安全的类,需要时刻注意对多个线程竞争访问资源的逻辑和安全做出正确的判断,对“原子”操作做出分析,并保证原子操作期间别的线程无法访问竞争资源。

6、当多个线程等待一个对象锁时,没有获取到锁的线程将发生阻塞。

7、死锁是线程间相互等待锁锁造成的,在实际中发生的概率非常的小。真让你写个死锁程序,不一定好使,呵呵。但是,一旦程序发生死锁,程序将死掉。

分享到:
评论

相关推荐

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

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

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

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

    线程 JAVA java线程 java线程第3版 java线程第2版第3版合集

    电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关线程的书籍) OReilly.Java.Threads.3rd.Edition.Sep.2004.eBook-DDU Java Thread Programming (Sams) java线程第二版中英文 java线程第二版中英文 ...

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

    本项目通过一个生产者消费者问题的实例,展示了如何在Java中实现线程间的同步与互斥。 生产者消费者问题是经典的并发问题之一,它涉及到两个类型的线程:生产者和消费者。生产者负责生成数据(产品),而消费者则...

    操作系统实验 多线程同步与互斥 java编写 有界面

    在“操作系统实验 多线程同步与互斥 java编写 有界面”的实验中,可能需要设计一个图形用户界面(GUI),通过按钮或事件触发线程的创建和同步操作,直观地展示线程间的交互和同步效果。例如,可以模拟银行账户转账,...

    java线程线程安全同步线程

    总的来说,理解和掌握Java线程的创建、状态管理、同步机制和线程安全是进行多线程编程的基础,这对于开发高效、稳定的并发程序至关重要。在实际编程中,应充分利用Java提供的工具和机制,避免潜在的并发问题,提升...

    Java多线程编程总结

    Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:线程的调度-优先级 Java线程:线程的调度-让步 Java线程:线程的调度-合并 Java线程:线程的调度-守护线程 Java线程:线程的...

    java多线程之并发锁

    在 Java 中,还有其他一些锁机制,例如 Semaphore、CountDownLatch 和 CyclicBarrier 等,它们都可以用来实现线程同步和线程安全。 Java 中的多线程编程需要充分考虑线程安全和锁机制的问题,否则可能会导致程序的...

    java线程同步java线程同步

    java线程同步java线程同步java线程同步

    Java多线程和同步

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

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

    本文将深入探讨Java多线程中的关键知识点,包括创建线程、主线程、线程优先级、线程组、线程同步以及线程间的通信。 1. **创建线程** 在Java中,可以通过两种方式创建线程:继承`Thread`类或实现`Runnable`接口。...

    java线程.pdf

    下面将围绕“Java线程”这一主题展开详细的介绍与解释。 ### Java线程基础 在Java语言中,线程是程序执行流的基本单元。一个标准的Java应用程序至少会有一个线程,即主线程,用于执行程序的主要逻辑。通过创建多个...

    java线程同步及通信

    Java线程同步与通信是多线程编程中的关键概念,用于解决并发访问共享资源时可能出现的数据不一致性和竞态条件问题。以下将详细介绍这两个主题,以及如何通过代码示例进行演示。 1. **线程同步**: 线程同步是确保...

    java线程同步详解

    Java中的线程同步还有其他工具,例如`java.util.concurrent`包中的`Semaphore`、`ReentrantLock`等,它们提供了更高级的同步控制,如信号量控制、公平锁、非公平锁等。 线程同步的主要目的是防止数据竞争(Data ...

    Java线程的同步与死锁

    ### Java线程的同步与死锁 #### 一、引言 在Java中,多线程编程是一项重要的技术,能够显著提升程序的性能和响应能力。然而,随着线程数量的增加,线程间的同步问题变得越来越复杂。本文将深入探讨Java线程中的同步...

    JAVA单线程多线程

    `synchronized`是Java中用于实现线程同步的关键字之一。它可以用来修饰方法或者代码块,确保被修饰的代码在同一时刻只能被一个线程访问。这是Java实现线程安全的一种基本手段。 ##### 使用synchronized修饰方法 当...

    Java 线程同步调用

    在Java中,实现线程同步最常用的方法之一是通过同步方法。在上述代码示例中,`MyThread`类中的`Sell()`方法被声明为`synchronized`。这意味着该方法在执行时会自动锁定当前对象实例,即`this`关键字。当一个线程正在...

    Java多线程同步.pdf

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

    java线程与并发编程实践

    Java线程与并发编程实践是Java开发者必备的技能之一,特别是在多核处理器和高并发应用环境中,有效地管理和利用线程能极大地提升程序的性能。本书《java线程与并发实践编程》由Jeff Friesen撰写,2017年2月出版,...

Global site tag (gtag.js) - Google Analytics