Java 中的线程是什么,如何创建和管理线程-中(十二)

news/2024/7/8 6:03:40

书接上文

三、Java 线程的同步

Java 中的线程同步是通过 synchronized 关键字实现的。在多线程环境下,当多个线程同时访问共享资源时,如果不进行同步控制,就会出现数据不一致、死锁等问题。为了保证多个线程之间的安全访问,需要使用 synchronized 关键字来进行同步控制。

synchronized 关键字可以用于方法或者代码块中,用于控制访问共享资源的顺序。当一个线程获取到一个对象的 synchronized 锁时,其他线程只能够等待该线程释放锁后才能继续执行。这种机制称为互斥锁。

在 Java 中,可以使用以下几种方式进行同步控制:

  1. 同步代码块

使用 synchronized 关键字修饰代码块,以控制访问共享资源的顺序。例如:

public class Test {
    private int count = 0;

    public void increment() {
        synchronized (this) { // 对象锁
            count++;
        }
    }

    public int getCount() {
        return count;
    }
}
  1. 同步方法

使用 synchronized 关键字修饰方法,以控制访问共享资源的顺序。例如:

public class Test {
    private int count = 0;

    public synchronized void increment() { // 对象锁
        count++;
    }

    public int getCount() {
        return count;
    }
}
  1. 重入锁

重入锁是一种可重复获取的互斥锁,可以避免死锁问题。重入锁需要使用 Lock 接口和 Condition 接口实现。例如:

import java.util.concurrent.locks.*;

public class Test {
    private int count = 0;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void increment() {
        lock.lock(); // 获取锁
        try {
            count++;
            condition.signalAll(); // 唤醒所有等待线程
        } finally {
            lock.unlock(); // 释放锁
        }
    }

    public int getCount() {
        return count;
    }
}

Java 线程的异步

Java 中的异步编程通常使用回调函数、Future 和 CompletableFuture 进行处理。在 Java 8 中,新增了 CompletableFuture 类,提供了更为强大的异步编程支持。

  1. 回调函数

回调函数是一种异步编程模式,可以在某个操作完成后自动调用指定的函数。在 Java 中,可以使用回调函数来处理异步任务。例如:

public interface MyCallback {
    void onCompleted(String result);
}

public class MyTask {
    public void run(MyCallback callback) {
        Thread t = new Thread(() -> {
            String result = doTask();
            callback.onCompleted(result);
        });
        t.start();
    }

    private String doTask() { // 模拟耗时操作
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "result";
    }
}

public class Test {
    public static void main(String[] args) {
        MyTask task = new MyTask();
        task.run(result -> System.out.println("Result: " + result));
        System.out.println("Task started.");
    }
}
  1. Future

Future 是一个异步编程模型,用于表示一个尚未完成的异步任务,并且可以在之后获取任务的结果。在 Java 中,可以使用 Future 来处理异步任务。例如:

import java.util.concurrent.*;

public class MyTask implements Callable<String> {
    public String call() throws Exception {
        return doTask();
    }

    private String doTask() { // 模拟耗时操作
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "result";
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<String> future = executor.submit(new MyTask());
       

可以使用 Future 的 get() 方法来等待任务的完成并获取结果,该方法会阻塞当前线程直到任务完成。例如:

import java.util.concurrent.*;

public class MyTask implements Callable<String> {
    public String call() throws Exception {
        return doTask();
    }

    private String doTask() { // 模拟耗时操作
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "result";
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<String> future = executor.submit(new MyTask());
        System.out.println("Task submitted.");

        String result = future.get(); // 等待任务完成并获取结果
        System.out.println("Result: " + result);

        executor.shutdown();
    }
}

未完待续


http://lihuaxi.xjx100.cn/news/1087680.html

相关文章

MCU固件升级系列1(STM32)

本系列将从升级流程、boot代码编写、APP代码编写以及固件打包来介绍&#xff0c;硬件选用STM32F407ZGT6&#xff08;手里只有&#xff09;&#xff0c;来完成这系列教程。 前言 为什么需要固件升级: 功能更新&#xff1a;随着产品的迭代和用户需求的变化&#xff0c;可能需要…

Prometheus监控系统存储容量优化攻略,让你的数据安心保存!

云原生监控领域不可撼动&#xff0c;Prometheus 是不是就没缺点&#xff1f;显然不是。 一个软件如果什么问题都想解决&#xff0c;就会导致什么问题都解决不好。所以Prometheus 也存在不足&#xff0c;广受诟病的问题就是 单机存储不好扩展。 1 真的需要扩展容量吗&#xff…

04_Uboot操作命令与其他命令

目录 BOOT 操作命令 bootz命令 bootm 命令 reset 命令 go 命令 run 命令 mtest 命令 BOOT 操作命令 uboot的本质工作是引导Linux,所以uboot肯定有相关的boot(引导)命令来启动Linux。常用的跟boot有关的命令有:bootz、bootm和boot。 bootz命令 要启动Linux,需要先将Lin…

OD工具之动态逆向分析技术实例分析

OD工具之动态逆向分析技术实例分析 vscode等编写cmp.cOD工具打开cmp.exe 卧槽垃圾高级软件工程真是烦人还是记录一下吧那么简单的几行没有手册搞半天都无力吐槽了 vscode等编写cmp.c 在vscode等编辑器中编写cmp.c文件&#xff1a; #include<stdio.h> int main() {int …

kotlin教程4:函数进阶

文章目录 可变参数尾递归函数函数式 kotlin教程&#xff1a;编程基础&#x1f48e;数据结构&#x1f48e;面向对象 可变参数 kotlin的函数定义非常灵活&#xff0c;既可以按照顺序传参&#xff0c;也可以通过参数名传参&#xff0c;而且可以设置参数默认值&#xff0c;这些在…

Linux安装MongoDB数据库,并内网穿透远程连接

文章目录 前言1. 配置Mongodb源2. 安装MongoDB3. 局域网连接测试4. 安装cpolar内网穿透5. 配置公网访问地址6. 公网远程连接7. 固定连接公网地址8. 使用固定地址连接 转载自Cpolar Lisa文章&#xff1a;Linux服务器安装部署MongoDB数据库 - 无公网IP远程连接「内网穿透」 前言 …

VS快捷键大全 | 掌握这些快捷键,助你调试快人一步

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

递归,回溯,分治(C++刷题笔记)

递归&#xff0c;回溯&#xff0c;分治&#xff08;C刷题笔记&#xff09; 78. 子集 力扣 预备知识 nums[][1,2,3],先将子集[1],[1,2],[1,2,3]打印 #include <bits/stdc.h>using namespace std;int main() {vector<int>nums;for (int i1;i<3;i){nums.push_…