Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块。
Note:
当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞
1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入.
例如:
public synchronized void synMethod(){
//方法体
}
如在线程t1中有语句obj.synMethod(); 那么由于synMethod被synchronized修饰,在执行该语句前, 需要先获得调用者obj的对象锁, 如果其他线程(如t2)已经锁定了obj (可能是通过obj.synMethod,也可能是通过其他被synchronized修饰的方法obj.otherSynMethod锁定的obj), t1需要等待直到其他线程(t2)释放obj, 然后t1锁定obj, 执行synMethod方法. 返回之前之前释放obj锁.
2.对某一代码块使用,synchronized后跟括号,括号里是变量,这样,一次只有一个线程进入该代码块.此时,线程获得的是成员锁
public class SynchronizedField {
private static Double balance = 100.0;
public static void main(String[] args) {
lockField();
}
public static void lockField() {
Thread withDrawThread = new WithdrawThread(10.0);
Thread depositThread = new Thread(new DepositThread(10.0));
withDrawThread.start();
depositThread.start();
}
private static final class WithdrawThread extends Thread {
private Double amount;
public WithdrawThread(Double amount) {
this.amount = amount;
}
public void run() {
synchronized (balance) {
System.out.println("Before withdrawing " + amount + ", the balance is " + balance);
balance -= amount;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Withdrew " + amount + ", the balance is " + balance);
}
}
}
private static final class DepositThread implements Runnable {
private Double amount;
public DepositThread(Double amount) {
this.amount = amount;
}
public void run() {
synchronized (balance) {
System.out.println("Before depositing " + amount + ", the balance is " + balance);
balance += amount;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Deposited " + amount + ", the balance is " + balance);
}
}
}
}
public class SynchronizedMethod {
private static Double balance = 100.0;
public static void main(String[] args) {
lockMethod();
}
public static void lockMethod() {
Thread depositThread1 = new Thread(new DepositThread(10.0));
Thread depositThread2 = new Thread(new DepositThread(10.0));
depositThread1.start();
depositThread2.start();
}
private static final class DepositThread implements Runnable {
private Double amount;
public DepositThread(Double amount) {
this.amount = amount;
}
public void run() {
deposit(amount);
}
}
public static synchronized void deposit(Double amount) {
System.out.println("Before depositing " + amount + ", the balance is " + balance);
balance += amount;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Deposited " + amount + ", the balance is " + balance);
}
}
Notes:
deposit方法不能写在DepositThread里
class lock和object lock
public class LearnVolatile {
public synchronized void SyncForInstance() {
for(int i=0; i<10; i++) {
System.out.println("SyncForInstance");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static synchronized void SyncForClass() {
for(int i=0; i<10; i++) {
System.out.println("SyncForClass");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static Thread t1 = new Thread() {
public void run() {
SyncForClass();
}
};
static Thread t2 = new Thread() {
public void run() {
new LearnVolatile().SyncForInstance();
}
};
public static void main(String[] args) {
t1.start();
t2.start();
}
}
结果如下:
SyncForClass
SyncForInstance
SyncForClass
SyncForInstance
……
public class LearnVolatile {
private static Lock lock = new ReentrantLock();
public void SyncForInstance() {
try {
lock.lock();
for(int i=0; i<10; i++) {
System.out.println("SyncForInstance");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
lock.unlock();
}
}
public static void SyncForClass() {
try {
lock.lock();
for(int i=0; i<10; i++) {
System.out.println("SyncForClass");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
lock.unlock();
}
}
static Thread t1 = new Thread() {
public void run() {
SyncForClass();
}
};
static Thread t2 = new Thread() {
public void run() {
new LearnVolatile().SyncForInstance();
}
};
public static void main(String[] args) {
t1.start();
t2.start();
}
}
结果如下:
SyncForClass
SyncForClass
SyncForClass
SyncForClass
SyncForClass
SyncForClass
SyncForClass
SyncForClass
SyncForClass
SyncForClass
SyncForInstance
SyncForInstance
SyncForInstance
SyncForInstance
SyncForInstance
SyncForInstance
SyncForInstance
SyncForInstance
SyncForInstance
SyncForInstance
Exception 1
public class LearnThread {
public static void main(String[] args) {
Thread t1 = new Thread() {
public void run() {
System.out.println("....");
}
};
t1.start();
t1.start();
}
}
....
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:704)
at com.jesse.core.learnvolatile.LearnThread.main(LearnThread.java:12)
Reason:线程的生命周期(dead)
①NEW:这种情况指的是,通过New关键字创建了Thread类(或其子类)的对象
②RUNNABLE:这种情况指的是Thread类的对象调用了start()方法,这时的线程就等待时间片轮转到自己这,以便获得CPU;第二种情况是线程在处于RUNNABLE状态时并没有运行完自己的run方法,时间片用完之后回到RUNNABLE状态;还有种情况就是处于BLOCKED状态的线程结束了当前的BLOCKED状态之后重新回到RUNNABLE状态。
③RUNNING:这时的线程指的是获得CPU的RUNNABLE线程,RUNNING状态是所有线程都希望获得的状态。
④DEAD:处于RUNNING状态的线程,在执行完run方法之后,就变成了DEAD状态了。
⑤BLOCKED:这种状态指的是处于RUNNING状态的线程,出于某种原因,比如调用了sleep方法、等待用户输入等而让出当前的CPU给其他的线程。
简单的死锁
public class DeadLock {
private static Lock lockA = new ReentrantLock();
private static Lock lockB = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread() {
public void run() {
try {
lockA.lock();
System.out.println("t1 get lockA");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1 is waiting lockB");
lockB.lock();
} finally {
lockA.unlock();
lockB.unlock();
}
}
};
Thread t2 = new Thread() {
public void run() {
try {
lockB.lock();
System.out.println("t2 got lockB");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2 is waiting for lockA");
lockA.lock();
} finally {
lockB.unlock();
lockA.unlock();
}
}
};
t1.start();
t2.start();
}
}
t2 got lockB
t1 get lockA
t2 is waiting for lockA
t1 is waiting for lockB
分享到:
相关推荐
### Java synchronized 关键字详解 #### 一、synchronized关键字简介 `synchronized`是Java语言提供的关键字之一,用于实现线程间的同步控制。通过在方法或代码块上使用`synchronized`,可以确保同一时间只有一个...
"Java 中 synchronized 用法详解" Synchronized 是 Java 语言中用于解决多线程共享数据同步问题的关键字。它可以作为函数的修饰符,也可以作为函数内的语句,用于实现同步方法和同步语句块。在 Java 中,...
Java 中的 synchronized 用法详解 Java 中的 synchronized 关键字是用于解决多线程并发问题的重要工具之一。它可以被用于方法、代码块和变量上,以实现对共享资源的互斥访问控制。本文将对 Java 中的 synchronized ...
在Android开发中,`synchronized`关键字是Java语言中用于实现线程同步的重要工具,它在多线程环境下确保了共享资源的安全访问。本测试案例深入探讨了`synchronized`的使用方法,包括同步单个对象、同步多个对象以及...
Java中的`synchronized`关键字是多线程编程中的一个重要概念,用于控制并发访问共享资源,以保证数据的一致性和完整性。这个关键词提供了互斥锁机制,防止多个线程同时执行同一段代码,确保了线程安全。 一、`...
在Java编程语言中,`synchronized`关键字是一个重要的并发控制机制,用于确保多线程环境下的数据一致性。本文将深入探讨`synchronized`的几种使用示例,包括方法加锁、代码块加锁(针对`this`和对象)以及静态方法...
### volatile与synchronized的区别 #### 一、锁的特性:互斥与可见性 在并发编程中,锁作为实现线程安全的一种手段,其核心作用在于提供两种特性:互斥和可见性。 - **互斥**:互斥是指在任何时刻,只允许一个...
"Java 锁机制 Synchronized" Java 锁机制 Synchronized 是 Java 语言中的一种同步机制,用于解决多线程并发访问共享资源时可能出现的一些问题。 Java 锁机制 Synchronized 的概念 在 Java 中,每个对象都可以被...
在Java多线程编程中,`synchronized`关键字是一个至关重要的工具,用于实现线程间的同步,以确保共享资源的安全访问。本实例大全将全面解析`synchronized`的使用方式,包括同步方法、同步语句块、类锁和对象锁。 ##...
在Java编程语言中,`synchronized`关键字是一个非常重要的并发控制机制,用于保证多线程环境下的数据一致性。本文将深入解析`synchronized`的工作原理、使用方式以及它在并发编程中的重要性。通过分析提供的源码,...
Java中的`synchronized`关键字是多线程编程中的一个重要概念,用于控制并发访问共享资源时的同步机制。在Java中,当多个线程试图同时访问和修改同一块代码或数据时,可能会导致数据不一致的问题。为了解决这个问题,...
### synchronized关键字的深入解析 #### 一、synchronized关键字的重要性 `synchronized`关键字在Java语言中扮演着极其重要的角色,它是实现线程安全的核心手段之一。通过`synchronized`关键字,开发人员可以在多...
《深入理解Java中的synchronized关键字》 在Java编程语言中,`synchronized`关键字是用于实现线程同步的重要工具,它的本质在于确保多线程环境下的数据一致性与安全性。通过`synchronized`,我们可以控制对共享资源...
### Synchronized关键字在Java中的应用 #### 概述 `synchronized`是Java语言中的一个关键字,主要用于实现线程同步,防止多个线程同时访问共享资源而导致的数据不一致问题。通过`synchronized`关键字,开发者可以...
在Java编程语言中,`synchronized`关键字是一个至关重要的概念,它主要用于实现线程同步,以确保多线程环境下的数据一致性与安全性。本篇文章将深入探讨`synchronized`的使用,包括其基本原理、使用方式以及实际应用...
Java中的`synchronized`关键字是多线程编程中用于同步控制的关键元素,它的主要目标是解决并发环境下多个线程对共享资源的访问冲突。在Java中,由于线程共享内存空间,如果没有适当的同步机制,可能会导致数据不一致...
在这个项目中,开发者利用`synchronized`关键字来实现线程同步,确保数据在生产与消费过程中的安全。 `synchronized`是Java中用于实现线程互斥的关键字,它提供了对共享资源的独占访问。当一个线程进入由`...
在Java编程中,synchronized和ReentrantLock都是用于实现线程同步的重要工具,它们在并发控制方面扮演着关键角色。然而,两者之间存在一些显著的区别,这些差异体现在功能、灵活性、性能以及使用场景上。 首先,...
`@synchronized`关键字是Apple提供的一种简便的同步机制,它可以帮助开发者确保在多线程环境下对共享资源进行原子性操作,防止数据竞争问题。本文将深入探讨`@synchronized`的工作原理、特点以及使用时需要注意的...