Java线程协作与共享变量保护代码示例

拾光
拾光
发布时间:2026-10-13| 3人浏览过
原创

Java 多线程开发中,既要解决多个线程交替执行的协作问题(如 wait/notify),又要保证共享状态修改的安全性。以下通过两段 Java 代码示例,分别展示如何控制线程顺序以及如何使用 synchronized 防止竞态条件。

场景一:主线程与子线程交替执行

该示例要求主线程先执行10次,紧接着子线程执行10次,如此往复循环50次。这展示了如何通过 synchronized 方法和 Object.wait()/notify() 机制实现线程间的有序调度。

第1步:定义业务逻辑类并封装同步锁

创建一个内部类 Business 用于处理线程交互逻辑。该类包含一个布尔标志位 tag 作为控制状态:

  • tag = true:表示当前应允许主线程执行,子线程需等待。
  • tag = false:表示当前应允许子线程执行,主线程需等待。

第2步:实现子线程的交替执行逻辑

在 Business 类中定义 synchronized void sub(int num) 方法供子线程调用: 1. 检查状态:若 tag 为 false(即轮到子线程时不满足条件,或上一轮子线程未释放),则调用 this.wait() 进入阻塞等待。 2. 执行任务:打印10次日志信息,表明子线程正在工作。 3. 切换状态并唤醒:将 tag 设为 true,并调用 notify() 唤醒处于等待队列中的主线程。

第3步:实现主线程的交替执行逻辑

定义 synchronized void main(int num) 方法供主线程调用,逻辑与子线程对称: 1. 检查状态:若 tag 为 true,说明此时轮到子线程,主线程调用 this.wait() 挂起。 2. 执行任务:打印10次日志信息。 3. 切换状态并唤醒:将 tag 设为 false,并调用 notify() 唤醒子线程。

第4步:启动线程并测试验证

在构造函数中启动一个新线程运行子线程的逻辑50次。随后在主线程中循环调用主线程逻辑50次。由于采用了精细的状态锁管理,两个线程能够严格交替输出结果。

package com.Thread.test;

/*
 * function:主线程执行10次,子线程执行10次,
 * 此过程重复50次
 */
public class ThreadProblem {

 public ThreadProblem() {
  
  final Business bus = new Business();
  new Thread(new Runnable() {
   
   public void run() {
   
   for(int j=0;j<50;j++) {
   
   bus.sub(j);
   }
   }
  }).start();
  
  for(int j=0;j<50;j++) {
  
   bus.main(j);
  }
 }
 class Business {
  
  private boolean tag=true;
  public synchronized void sub(int num) {
  
   if(!tag) {
   
   try {
    this.wait();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   }
   for(int i=0;i<10;i++)
   {
   System.out.println("sub thread "+i+",loop "+num+".");
   }
   
   tag=false;
   notify();
  }
  
  public synchronized void main(int num) {
  
   if(tag) {
   
   try {
    this.wait();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   }
   for(int i=0;i<10;i++) {
   
   System.out.println("main thread "+i+",loop "+num+".");
   }
   
   tag=true;
   notify();
  }
 }
 
 public static void main(String[] args) {
  
  ThreadProblem problem = new ThreadProblem();
 }
}

场景二:多线程同时修改共享变量的安全性

该示例创建了4个线程,共享一个静态整型变量 j。其中两个线程负责对 j 进行加1操作,另外两个线程负责减1。本段代码展示了使用 synchronized 关键字修饰实例方法来避免数据竞争(Race Condition)。

第1步:定义共享资源与线程结构

声明一个静态变量 private static int j=0 作为共享计数器。为了保证线程安全,我们将自增和自减的操作封装在一个内部类 A 的方法中。

第2步:确保操作的原子性

在类 A 中定义了 synchronized void add1() 和 synchronized void delete1()。 1. synchronized 保证了同一时刻只有一个线程能访问这两个方法。 2. 在执行 j++ 或 j-- 期间,其他试图访问相同锁的线程会被阻塞,直到当前操作结束并打印最新值。 3. 这样可以确保输出的计数结果是准确且连贯的,不会出现因并发更新导致的脏读或丢失更新。

第3步:启动多线程序列测试

在 Demo1 构造函数中进行初始化: - 开启两个线程,每个线程循环调用 a.add1() 5次。 - 开启另外两个线程,每个线程循环调用 a.delete1() 5次。 由于总共有 2 × 5 = 10 次加法,以及 2 × 5 = 10 次减法,最终预期结果为 0。尽管执行过程中线程会穿插执行,但由于互斥锁的存在,每个步骤都是原子的。

package com.Thread.test;
//实现4个线程,两个线程加1,两个线程减1
public class Demo1 {

 private static int j=0;
 private A a = new A();
 //构造函数
 public Demo1() {
  
  System.out.println("j的初始值为:"+j);
  for(int i=0;i<2;i++) {
  
   new Thread(new Runnable(){
   
   public void run() {
    
    for(int k=0;k<5;k++){
    a.add1();
    }
   }
  }).start();
  
   new Thread(new Runnable(){
   
   public void run() {
    
    for(int k=0;k<5;k++)
    {
    a.delete1();
    }
   }
  }).start();
  }
 }
 class A {
  
  public synchronized void add1() {
  
   j++;
   System.out.println(Thread.currentThread().getName()+"对j加1,目前j="+Demo1.j);
  }
  
     public synchronized void delete1() {
  
   j--;
   System.out.println(Thread.currentThread().getName()+"对j减1,目前j="+Demo1.j);
  }
 }
 
 //用于测试的主函数
 public static void main(String[] args) {
  
  Demo1 demo = new Demo1();
 }
}

以上就是Java线程重复执行以及操作共享变量的详细内容,更多关于Java并发编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。