Java Concurrency (1)

本文探讨了多线程环境中共享内存的概念,包括堆内存中变量的可见性和原子性问题。详细讨论了可见性问题如何导致数据竞争,并介绍了正确同步对于确保数据访问顺序的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Memory that can be shared betweenthreads is called shared memory or heap memory. The term variable as used inthis technical report refers to both fields and array elements. Variables thatare shared between threads are referred to as shared variables. All instance fields,static fields, and array elements are shared variables allocated in heapmemory. Local variables, formal method parameters, and exception-handlerparameters are never shared between threads and are not affected by the memorymodel.

The visibility of writes toshared variables can be problematic because the value of a shared variable maybe cached and not written to main memory immediately. Consequently, anotherthread may read a stale value of the variable.

A further concern is thatconcurrent executions of code are typically interleaved, and statements may bereordered b the compiler or runtime system to optimize performance. Thisresults in execution orders that are not immediately obvious when the sourcecode is examined. Failure to account for possible reordering is a common sourceof data races.

Volatile accesses do notguarantee the atomicity of composite operations such incrementing a variable.Consequently, volatile is not applicable in cases where the atomicity ofcomposite operations must be guaranteed.

A correctly synchronized programis one whose sequentially consistent executions do not have any data races.

Correct visibility guaranteesthat multiple threads accessing shared data can view each others’ results, butdoes not establish the order of when each thread reads or writes the data.Correct synchronization guarantees that threads access data in a proper order.

### Java 并发编程中的多线程同步与锁 #### synchronized 关键字 `synchronized` 是 Java 中最基本也是最常用的同步机制之一。此关键字可用于修饰方法或代码块,确保在同一时刻仅有一个线程能执行相应的方法或代码片段[^1]。 ```java public class Counter { private int count; public synchronized void increment() { // 同步整个方法 this.count++; } public void decrement() { synchronized (this) { // 或者只同步部分代码块 this.count--; } } } ``` #### 自旋锁(Spin Lock) 除了 `synchronized`,另一种常见的锁定策略是在 JDK 1.5 版本引入的自旋锁。当某个线程尝试获取已被占用的锁时,不会立即进入阻塞状态而是会持续循环检查锁的状态直至获得锁为止。这种方式适用于竞争不激烈且持有时间较短的情况,在某些场景下可减少上下文切换带来的开销[^2]。 ```java class SpinLockDemo { private final AtomicReference<Thread> sign = new AtomicReference<>(); public void lock() { Thread current = Thread.currentThread(); while (!sign.compareAndSet(null, current)) {} } public void unlock() { Thread current = Thread.currentThread(); sign.compareAndSet(current, null); } } ``` #### 使用 ThreadLocal 避免竞态条件 为了进一步简化并发环境下的数据管理并提升效率,Java 还提供了 `ThreadLocal` 类型来为每个线程创建独立的数据副本。这不仅解决了传统意义上的资源争抢问题,同时也降低了因频繁加解锁操作而造成的性能损耗[^3]。 ```java public class Task implements Runnable { private static final ThreadLocal<Integer> threadLocalValue = ThreadLocal.withInitial(() -> 0); @Override public void run() { Integer value = threadLocalValue.get(); // 获取当前线程独有的值 System.out.println(Thread.currentThread().getName() + " has value: " + value); try { Thread.sleep(100); // 模拟耗时任务 } catch (InterruptedException e) {} threadLocalValue.set(value + 1); // 更新当前线程独有值 System.out.println(Thread.currentThread().getName() + " updated to : " + threadLocalValue.get()); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值