快捷搜索:  汽车  科技

java架构牛逼代码(七爪源码Java中的同步)

java架构牛逼代码(七爪源码Java中的同步)类锁在Java中,每个对象都会有一个监控对象,也就是Java对象的锁,通常称为“内置锁”或“对象锁”。一个类中可以有多个对象,所以每个对象都有自己的对象锁,互不干扰。可见性:必须保证在释放锁之前,对共享变量所做的修改对于后续获取锁的另一个线程是可见的(即在获取锁时应该获取最新的共享变量的值),否则另一个thread 不一致的原因可能是继续对本地缓存的副本进行操作。对象锁和类锁对象锁定

java架构牛逼代码(七爪源码Java中的同步)(1)

概念

Synchronized是Java中的一个关键字,它使用锁机制来实现同步。

锁定机构具有以下两个特点。

互斥:即只允许一个线程同时持有一个对象锁,该特性用于实现多线程中的协调机制,使得只有一个线程可以对代码块进行同步(复合操作) ) 同时。使用权。互斥也经常被称为操作的原子性。

可见性:必须保证在释放锁之前,对共享变量所做的修改对于后续获取锁的另一个线程是可见的(即在获取锁时应该获取最新的共享变量的值),否则另一个thread 不一致的原因可能是继续对本地缓存的副本进行操作。

对象锁和类锁

对象锁定

在Java中,每个对象都会有一个监控对象,也就是Java对象的锁,通常称为“内置锁”或“对象锁”。一个类中可以有多个对象,所以每个对象都有自己的对象锁,互不干扰。

类锁

在Java中,每个类也有一个锁,可以称为类锁。类锁是通过对象锁实现的,即类的类对象锁。每个类只有一个 Class 对象,因此每个类只有一个类锁。

同步使用分类

同步的使用可以分为两个维度。

1 按修饰对象分类

synchronized 可以装饰方法和代码块。

Decorated code block - synchronized(this|object) {} - synchronized(class.class) {}Modification method - Decorate a non-static method - Decorate static methods

2 按获取锁分类

Acquire object lock - synchronized(this|object) {} - Decorate a non-static methodAcquire class lock - Synchronized(class.class) {} - Decorate static methods non-static methods

synchronized的使用详解

这里根据获取锁的分类来分析synchronized的用法。

文章中的所有示例都使用这四个线程。

public class medium01Test{ public static void main(String[] args) { SyncThread syncThread = new SyncThread(); Thread F_thread1 = new Thread(new SyncThread() "F_thread1"); Thread F_thread2 = new Thread(new SyncThread() "F_thread2"); Thread F_thread3 = new Thread(syncThread "F_thread3"); Thread F_thread4 = new Thread(syncThread "F_thread4"); F_thread1.start(); F_thread2.start(); F_thread3.start(); F_thread4.start(); } }

1 使用对象锁

该对象是新创建的,与其他对象无关。

class SyncThread implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName() "_Sync: " new SimpleDateFormat("HH:mm:ss").format(new Date())); synchronized (new SyncThread()) { try { System.out.println(Thread.currentThread().getName() "_Sync_Start: " new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() "_Sync_End: " new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } F_thread1_Sync: 23:20:55 F_thread2_Sync: 23:20:55 F_thread4_Sync: 23:20:55 F_thread3_Sync: 23:20:55 F_thread1_Sync_Start: 23:20:55 F_thread2_Sync_Start: 23:20:55 F_thread4_Sync_Start: 23:20:55 F_thread3_Sync_Start: 23:20:55 F_thread4_Sync_End: 23:20:57 F_thread1_Sync_End: 23:20:57 F_thread3_Sync_End: 23:20:57 F_thread2_Sync_End: 23:20:57

四个线程同时开始和结束,因为作为锁的对象和线程属于不同的实例。

2 使用类锁,不管是哪个类,都会被拦截

class SyncThread implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName() "_Sync: " new SimpleDateFormat("HH:mm:ss").format(new Date())); synchronized (SyncThread.class) { try { System.out.println(Thread.currentThread().getName() "_Sync_Start: " new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() "_Sync_End: " new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } } F_thread1_Sync: 23:23:11 F_thread2_Sync: 23:23:11 F_thread3_Sync: 23:23:11 F_thread4_Sync: 23:23:11 F_thread1_Sync_Start: 23:23:11 F_thread1_Sync_End: 23:23:13 F_thread4_Sync_Start: 23:23:13 F_thread4_Sync_End: 23:23:15 F_thread3_Sync_Start: 23:23:15 F_thread3_Sync_End: 23:23:17 F_thread2_Sync_Start: 23:23:17 F_thread2_Sync_End: 23:23:19

可以发现,使用类锁一次只能通过一个。

3 使用这个对象锁

class SyncThread implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName() "_Sync: " new SimpleDateFormat("HH:mm:ss").format(new Date())); synchronized (this) { try { System.out.println(Thread.currentThread().getName() "_Sync_Start: " new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() "_Sync_End: " new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } } F_thread1_Sync: 23:23:56 F_thread2_Sync: 23:23:56 F_thread3_Sync: 23:23:56 F_thread1_Sync_Start: 23:23:56 F_thread4_Sync: 23:23:56 F_thread2_Sync_Start: 23:23:56 F_thread3_Sync_Start: 23:23:56 F_thread1_Sync_End: 23:23:58 F_thread2_Sync_End: 23:23:58 F_thread3_Sync_End: 23:23:58 F_thread4_Sync_Start: 23:23:58 F_thread4_Sync_End: 23:24:00

线程 1 和 2 同时结束,线程 3 和 4 一个接一个。 原因是 3 和 4 属于同一个实例。

4 使用同步修改方法

作用域是整个方法,所以方法中的所有代码都是同步的。

class SyncThread implements Runnable { @Override public void run() { sync(); } public synchronized void sync() { System.out.println(Thread.currentThread().getName() "_Sync: " new SimpleDateFormat("HH:mm:ss").format(new Date())); try { System.out.println(Thread.currentThread().getName() "_Sync_Start: " new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() "_Sync_End: " new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } F_thread2_Sync: 23:26:38 F_thread3_Sync: 23:26:38 F_thread2_Sync_Start: 23:26:38 F_thread3_Sync_Start: 23:26:38 F_thread1_Sync: 23:26:38 F_thread1_Sync_Start: 23:26:38 F_thread3_Sync_End: 23:26:40 F_thread2_Sync_End: 23:26:40 F_thread1_Sync_End: 23:26:40 F_thread4_Sync: 23:26:40 F_thread4_Sync_Start: 23:26:40 F_thread4_Sync_End: 23:26:42

对于非静态方法,会拦截同一个实例的线程访问,可以同时访问不同的实例。 也就是此时默认的对象锁(this)。

class SyncThread implements Runnable { @Override public void run() { sync(); } public synchronized static void sync() { System.out.println(Thread.currentThread().getName() "_Sync: " new SimpleDateFormat("HH:mm:ss").format(new Date())); try { System.out.println(Thread.currentThread().getName() "_Sync_Start: " new SimpleDateFormat("HH:mm:ss").format(new Date())); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() "_Sync_End: " new SimpleDateFormat("HH:mm:ss").format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } } F_thread1_Sync: 23:28:47 F_thread1_Sync_Start: 23:28:47 F_thread1_Sync_End: 23:28:49 F_thread4_Sync: 23:28:49 F_thread4_Sync_Start: 23:28:49 F_thread4_Sync_End: 23:28:51 F_thread3_Sync: 23:28:51 F_thread3_Sync_Start: 23:28:51 F_thread3_Sync_End: 23:28:53 F_thread2_Sync: 23:28:53 F_thread2_Sync_Start: 23:28:53 F_thread2_Sync_End: 23:28:55

静态方法默认类锁。

结论

  1. 对于静态方法,由于此时还没有生成对象,所以只能使用类锁。
  2. 只要使用类锁,所有线程都会被拦截,只能访问一个线程。
  3. 对于对象锁(this),如果是同一个实例,会顺序访问,如果是不同的实例,可以同时访问。
  4. 如果对象锁与被访问的对象无关,则两者会同时被访问。

关注七爪网,获取更多APP/小程序/网站源码资源!

猜您喜欢: