Java详解之I/O[BIO、NIO、AIO使用方法和示范代码]

前言:

小弟能力不足,认知有限,难免考虑不全面,希望大佬能给出更好的建议,指出存在的问题和不足,在此跪谢。

IO发展史

Java中对于I/O能力的支持主要分为三个比较关键的阶段:

BIO

第一个阶段是起步阶段JDK1.0 ~ JDK1.3,这个阶段JDK是处于BIO阶段的,也就是同步阻塞模式,该阶段的类库还非常的初级,对系统层面的一些网络编程的API都没有进行实现,因此这个阶段的很多大型应用服务器都采用C或者C++语言来进行开发的,因为C或者C++可以直接调用操作系统提供的非阻塞I/O能力;

NIO

第二个阶段从JDK1.4开始的,从JDK1.4开始,Java新增了java.nio的包,正式支持的NIO,提供了许多非阻塞I/O开发的API和类库;

AIO

第三个阶段是从JDK1.7开始的,这一次是对原来的NIO类库进行了升级,官方称为NIO 2.0,该版本不但强化了原来的基于I/O多路复用模型的NIO模式,同时新增了异步的AIO功能,所以也有很多人称之为AIO。

各个IO介绍

BIO

在Java中,BIO(Blocking I/O)指的是阻塞式I/O,是一种基本的I/O模型。它的实现原理相对简单,但在高并发场景下性能较差。下面我将详细介绍BIO的实现原理。

  1. 阻塞式I/O
    在BIO中,当一个线程在进行I/O操作时,如果数据没有准备好,该线程会被阻塞,直到数据准备好并被读取或写入。这意味着一个线程只能处理一个连接,如果有大量连接同时到来,就需要大量线程来处理,这会导致资源消耗过大。

  2. 实现原理

    • 服务端:服务端通过ServerSocket监听客户端的连接请求。当有连接请求到来时,服务端会创建一个新的线程来处理该连接。
    • 客户端:客户端通过Socket向服务端发起连接请求。一旦连接建立,客户端和服务端之间可以进行数据的读取和写入。
  3. 服务端示例代码

    思路:在服务端的代码中,我们创建了一个固定大小的线程池,用于处理客户端的连接请求。每当有客户端连接时,就会将连接交给线程池中的一个线程来处理,这样可以提高并发处理能力。同时,我们定义了一个ClientHandler类来处理客户端的请求,这样可以更好地组织代码逻辑。

    这样的设计可以更好地满足企业级生产环境的要求,提高了系统的并发处理能力和稳定性。当然你还可以加入日志打印,更好的排查问题,但是因为这种已经过时,所以只是简单示例。

    import java.io.*;
    import java.net.*;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;public class Server {public static void main(String[] args) {ServerSocket serverSocket = null;ExecutorService executor = Executors.newFixedThreadPool(10); // 创建一个固定大小的线程池try {serverSocket = new ServerSocket(8080);System.out.println("Server started. Waiting for client...");while (true) {// 等待客户端连接Socket clientSocket = serverSocket.accept();System.out.println("Client connected: " + clientSocket.getRemoteSocketAddress());// 使用线程池处理客户端请求executor.execute(new ClientHandler(clientSocket));}} catch (IOException e) {e.printStackTrace();} finally {try {if (serverSocket != null) {serverSocket.close();}executor.shutdown(); // 关闭线程池} catch (IOException e) {e.printStackTrace();}}}private static class ClientHandler implements Runnable {private Socket clientSocket;public ClientHandler(Socket clientSocket) {this.clientSocket = clientSocket;}@Overridepublic void run() {try {// 获取输入流BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));// 获取输出流PrintWriter output = new PrintWriter(clientSocket.getOutputStream(), true);// 读取客户端发送的数据String clientMessage = input.readLine();System.out.println("Received from client: " + clientMessage);// 向客户端发送数据output.println("Hello, client!");// 关闭流和连接input.close();output.close();clientSocket.close();} catch (IOException e) {e.printStackTrace();}}}
    }
  4. 客户端实例代码实现:

    import java.io.*;
    import java.net.*;public class Client {public static void main(String[] args) {Socket socket = null;try {socket = new Socket("localhost", 8080);System.out.println("Connected to server.");// 获取输入流BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));// 获取输出流PrintWriter output = new PrintWriter(socket.getOutputStream(), true);// 向服务端发送数据output.println("Hello, server!");// 读取服务端发送的数据String serverMessage = input.readLine();System.out.println("Received from server: " + serverMessage);// 关闭流和连接input.close();output.close();socket.close();} catch (IOException e) {e.printStackTrace();} finally {try {if (socket != null) {socket.close();}} catch (IOException e) {e.printStackTrace();}}}
    }

  5. 适用场景
    BIO适用于连接数较少且吞吐量要求不高的场景,例如传统的Socket通信应用。

  6. 局限性
    由于BIO的阻塞特性,它在高并发场景下表现较差,因为大量线程会因为I/O阻塞而处于等待状态,导致资源浪费。

总的来说,BIO是一种简单直观的I/O模型,但在高并发场景下存在性能瓶颈。随着业务的发展,通常会选择更高效的NIO(Non-blocking I/O)或者AIO(Asynchronous I/O)来替代BIO。

NIO

在Java中,NIO(New I/O)是一种非阻塞I/O模型,相比于传统的BIO(Blocking I/O),NIO具有更高的并发处理能力。下面我将详细介绍NIO的实现原理。

  1. 非阻塞I/O
    NIO的核心是非阻塞I/O,它允许一个线程处理多个连接,当一个连接上的I/O操作不可立即完成时,线程可以去处理其他连接,而不是被阻塞。

  2. 核心组件

    • 通道(Channel):用于读取和写入数据,可以是文件、套接字等。
    • 缓冲区(Buffer):用于临时存储数据,读取数据到缓冲区或将缓冲区中的数据写入通道。
    • 选择器(Selector):用于监听多个通道的事件,例如连接就绪、读就绪、写就绪等。
  3. 实现原理

    • 服务端:服务端通过ServerSocketChannel监听连接请求,一旦有连接到来,会将该连接注册到Selector上,并监听连接就绪事件。
    • 客户端:客户端通过SocketChannel向服务端发起连接请求,连接建立后也会注册到Selector上。
  4. NIO服务器端示例代码:
    实现思路:

    在以下代码中,我们引入了日志打印服务,使用了Java自带的Logger类来记录日志。同时,我们使用了线程池来处理客户端的连接请求和数据读写操作,以提高并发处理能力。对于各种可能遇到的问题,比如连接超时、网络异常、数据读写异常等,我们在相应的位置进行了异常处理,并记录了相应的日志,以便于排查和解决问题。

    这样的设计更加符合企业级生产规范,提高了系统的并发处理能力和稳定性,并且对各种异常情况进行了处理,使得系统更加健壮可靠。

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.*;
    import java.util.Iterator;
    import java.util.Set;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.logging.Logger;public class NIOServer {private static final Logger logger = Logger.getLogger(NIOServer.class.getName());private static final ExecutorService executor = Executors.newFixedThreadPool(10);public static void main(String[] args) {try {Selector selector = Selector.open();ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> keyIterator = selectedKeys.iterator();while (keyIterator.hasNext()) {SelectionKey key = keyIterator.next();keyIterator.remove();if (key.isAcceptable()) {executor.execute(() -> handleAccept(key, selector));} else if (key.isReadable()) {executor.execute(() -> handleRead(key));}}}} catch (IOException e) {logger.severe("Error in NIO server: " + e.getMessage());}}private static void handleAccept(SelectionKey key, Selector selector) {try {ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();SocketChannel clientChannel = serverSocketChannel.accept();clientChannel.configureBlocking(false);clientChannel.register(selector, SelectionKey.OP_READ);} catch (IOException e) {logger.severe("Error in handleAccept: " + e.getMessage());}}private static void handleRead(SelectionKey key) {try {SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = clientChannel.read(buffer);if (bytesRead == -1) {clientChannel.close();key.cancel();} else if (bytesRead > 0) {buffer.flip();byte[] data = new byte[bytesRead];buffer.get(data);logger.info("Received from client: " + new String(data));// 可以在这里处理接收到的数据}} catch (IOException e) {logger.severe("Error in handleRead: " + e.getMessage());}}
    }
  5. NIO客户端的代码:

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SocketChannel;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.logging.Logger;public class NIOClient {private static final Logger logger = Logger.getLogger(NIOClient.class.getName());private static final ExecutorService executor = Executors.newFixedThreadPool(10);public static void main(String[] args) {try {SocketChannel socketChannel = SocketChannel.open();socketChannel.configureBlocking(false);socketChannel.connect(new InetSocketAddress("localhost", 8080));while (!socketChannel.finishConnect()) {// 等待连接完成}executor.execute(() -> {try {String message = "Hello, server!";ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());socketChannel.write(buffer);buffer.clear();int bytesRead = socketChannel.read(buffer);if (bytesRead > 0) {buffer.flip();byte[] data = new byte[bytesRead];buffer.get(data);logger.info("Received from server: " + new String(data));// 可以在这里处理接收到的数据}} catch (IOException e) {logger.severe("Error in NIO client: " + e.getMessage());} finally {try {socketChannel.close();} catch (IOException e) {logger.severe("Error in closing socket channel: " + e.getMessage());}}});} catch (IOException e) {logger.severe("Error in NIO client: " + e.getMessage());}}
    }

  6. 适用场景
    NIO适用于高并发的网络应用,例如Web服务器、聊天服务器等,能够更高效地处理大量连接。

总的来说,NIO通过Selector、Channel和Buffer的组合,实现了非阻塞I/O,提高了系统的并发处理能力。然而,NIO编程相对复杂,需要处理事件的就绪状态,因此在实际应用中通常会使用NIO框架或者基于NIO的高级框架,如Netty。

AIO

在Java中,AIO(Asynchronous I/O)是一种基于事件和回调机制的I/O模型,相比于传统的BIO(Blocking I/O)和NIO(Non-blocking I/O),AIO更加适用于处理大量并发连接。下面我将详细介绍AIO的实现原理。

  1. 异步I/O
    AIO的核心是异步I/O,它允许一个线程在等待数据就绪的同时继续做其他事情,当数据就绪后通过回调机制来处理数据。这种模型相比于NIO更加灵活,因为不需要手动检查就绪状态,而是通过事件通知来处理。

  2. 核心组件

    • 异步通道(AsynchronousChannel):用于进行异步I/O操作,包括文件和套接字等。
    • 异步操作结果(AsynchronousResult):用于存储异步操作的结果,可以通过回调方式获取结果。
    • 异步处理器(AsynchronousHandler):用于处理异步操作完成后的回调。
  3. 实现原理

    • 服务端:服务端通过AsynchronousServerSocketChannel监听连接请求,一旦有连接到来,会调用accept方法,并通过回调方式处理连接就绪事件。
    • 客户端:客户端通过AsynchronousSocketChannel向服务端发起连接请求,连接建立后也可以通过回调方式处理后续的读写操作。
  4. 简单的AIO服务器示例代码
    实现思路:针对企业级生产环境中高可用的通信需求,以下是一个更完善的AIO服务端和客户端的Java代码。该代码考虑了各种可能遇到的问题,并给出了切实可行的异常解决方案。同时,引入了日志打印服务,使用了Java自带的Logger类来记录日志,并使用了线程池来处理客户端的连接请求和数据读写操作,以提高并发处理能力。

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.AsynchronousServerSocketChannel;
    import java.nio.channels.AsynchronousSocketChannel;
    import java.nio.channels.CompletionHandler;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    import java.util.logging.Logger;public class AIOServer {private static final Logger logger = Logger.getLogger(AIOServer.class.getName());private static final ExecutorService executor = Executors.newFixedThreadPool(10);public static void main(String[] args) {try {AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();serverSocketChannel.bind(new InetSocketAddress(8080));serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {@Overridepublic void completed(AsynchronousSocketChannel clientChannel, Void attachment) {serverSocketChannel.accept(null, this); // 接受下一个连接executor.execute(() -> handleRead(clientChannel));}@Overridepublic void failed(Throwable exc, Void attachment) {logger.severe("Error in accepting connection: " + exc.getMessage());}});// 阻止主线程退出Thread.currentThread().join();} catch (IOException | InterruptedException e) {logger.severe("Error in AIO server: " + e.getMessage());}}private static void handleRead(AsynchronousSocketChannel clientChannel) {ByteBuffer buffer = ByteBuffer.allocate(1024);clientChannel.read(buffer, null, new CompletionHandler<Integer, Void>() {@Overridepublic void completed(Integer bytesRead, Void attachment) {if (bytesRead == -1) {try {clientChannel.close();} catch (IOException e) {logger.severe("Error in closing client channel: " + e.getMessage());}return;}buffer.flip();byte[] data = new byte[bytesRead];buffer.get(data);logger.info("Received from client: " + new String(data));// 可以在这里处理接收到的数据buffer.clear();clientChannel.read(buffer, null, this); // 继续读取数据}@Overridepublic void failed(Throwable exc, Void attachment) {logger.severe("Error in reading from client: " + exc.getMessage());}});}
    }
  5. 简单的AIO客户端示例代码

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.AsynchronousSocketChannel;
    import java.nio.channels.CompletionHandler;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.logging.Logger;public class AIOClient {private static final Logger logger = Logger.getLogger(AIOClient.class.getName());private static final ExecutorService executor = Executors.newFixedThreadPool(10);public static void main(String[] args) {try {AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open();socketChannel.connect(new InetSocketAddress("localhost", 8080), null, new CompletionHandler<Void, Void>() {@Overridepublic void completed(Void result, Void attachment) {String message = "Hello, server!";ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());socketChannel.write(buffer, null, new CompletionHandler<Integer, Void>() {@Overridepublic void completed(Integer bytesWritten, Void attachment) {if (buffer.hasRemaining()) {socketChannel.write(buffer, null, this); // 继续写入数据} else {buffer.clear();socketChannel.read(buffer, null, new CompletionHandler<Integer, Void>() {@Overridepublic void completed(Integer bytesRead, Void attachment) {buffer.flip();byte[] data = new byte[bytesRead];buffer.get(data);logger.info("Received from server: " + new String(data));// 可以在这里处理接收到的数据}@Overridepublic void failed(Throwable exc, Void attachment) {logger.severe("Error in reading from server: " + exc.getMessage());}});}}@Overridepublic void failed(Throwable exc, Void attachment) {logger.severe("Error in writing to server: " + exc.getMessage());}});}@Overridepublic void failed(Throwable exc, Void attachment) {logger.severe("Error in connecting to server: " + exc.getMessage());}});// 阻止主线程退出Thread.currentThread().join();} catch (IOException | InterruptedException e) {logger.severe("Error in AIO client: " + e.getMessage());}}
    }

  6. 适用场景
    AIO适用于需要处理大量并发连接且对性能要求较高的场景,例如高性能的网络服务器、金融交易系统等。

总的来说,AIO通过异步I/O和事件回调机制,实现了高效的并发处理能力,相比于NIO更加灵活和高效。然而,AIO在Java中的实现相对较新,需要较高的技术要求,因此在实际应用中通常会使用成熟的AIO框架或者基于AIO的高级框架。

在Java中,有一些成熟的AIO框架或者基于AIO的高级框架,它们提供了更加便捷和高效的异步I/O编程方式。以下是一些常用的框架:

  1. Netty
    Netty是一个基于NIO的高性能网络通信框架,但它也提供了对AIO的支持。Netty的异步事件驱动模型和高度可定制的架构使得它成为构建高性能、可扩展的网络应用程序的理想选择。Netty提供了丰富的功能,包括TCP/UDP传输、HTTP编解码、WebSocket支持等,广泛应用于网络服务器、分布式系统等领域。

  2. Grizzly
    Grizzly是一个基于NIO的高性能网络框架,它提供了对AIO的支持,并且具有高度可扩展性和灵活性。Grizzly可以用于构建高性能的Web服务器、应用服务器等网络应用。

  3. Apache MINA
    Apache MINA是一个基于NIO的网络应用框架,它提供了对AIO的支持,并且具有良好的扩展性和灵活性。MINA可以用于构建各种类型的网络应用,包括游戏服务器、即时通讯服务器等。

这些框架都提供了对AIO的封装和抽象,简化了异步I/O编程的复杂性,同时提供了丰富的功能和高性能的网络通信能力。在实际应用中,选择合适的框架取决于具体的需求和项目背景,但无论选择哪个框架,都可以极大地简化异步I/O编程的复杂性,提高开发效率和系统性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/166951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈安科瑞直流电表在印尼某基站的应用

摘要&#xff1a;本文介绍了安科瑞直流电表在印尼的应用。主要用于印尼某基站的电流电压电能的计量&#xff0c;配合霍尔传感器对基站进行计量。 Abstract: This article introduces the application of Acrel DC meters in base station in Indonesia.The device is measuri…

【此时不应有 \anaconda3\envs\ blenderproc \Library\ssl\cacert.pem】问题已解决

conda 创建新环境后&#xff0c;使用conda activate blenderproc命令激活环境时出现以下错误&#xff1a; 此时不应有 \anaconda3\envs\ blenderproc \Library\ssl\cacert.pem 其他博客里面https://blog.csdn.net/weixin_46599926/article/details/132576960解释这个是因为co…

前端 HTML 和 JavaScript 的基础知识有哪些?

前端开发是Web开发的一个重要领域&#xff0c;涉及到HTML&#xff08;Hypertext Markup Language&#xff09;和JavaScript两个主要的技术。HTML用于定义网页的结构和内容&#xff0c;而JavaScript用于实现网页的交互和动态效果。以下是前端HTML和JavaScript的基础知识&#xf…

如何做好测试管理岗?深度分析职业规划

在给学生做职业规划的时候&#xff0c;经常就有同学说&#xff1a;我以后要做管理岗&#xff01;其实对于很多刚入行的同学&#xff0c;可能说这句话的时候并没有真正理解管理岗需要做什么事&#xff0c;以及需要具备什么样的技能。所以&#xff0c;作为资深测试经理&#xff0…

飞翔的小鸟——Java

一、创建文件、包、类、插入图片文件 二、app包 1、Gameapp类&#xff08;运行游戏&#xff09; package app;import main.GameFrame;public class Gameapp {public static void main(String[] args) {//游戏的入口new GameFrame();} } 三、main包 1、Barrier&#xff08…

无需外接显示器,直接使用windows安装树莓派系统并可远程桌面登录

准备工作: 1.安装树莓派官方烧录工具 raspberry pi imager 2.下载树莓派系统镜像(也可选择在线下载安装) 打开imager工具&#xff0c;选择需要安装包树莓派版本 点击"NEXT"&#xff0c;在弹出的选项中选择编辑设置。 设置登录名和密码&#xff0c;已经所连接的wif…

统一用户桌面壁纸怎么设置

统一用户桌面壁纸的设置方法有多种&#xff0c;以下列举两种&#xff1a; 方法一&#xff1a;个人更换壁纸 1、右键桌面&#xff0c;鼠标选择“个性化”。 2、进入个性化之后&#xff0c;单击下面的“桌面背景”图标。 3、点击“浏览”选择自己备好的桌面壁纸&#xff0c;点击…

昇腾Atlas 200I DK A2实现安全帽识别

文章目录 环境依赖编译测试总结 环境依赖 软件版本说明获取方式mxVision5.0.RC2mxVision软件包获取方式Ascend-CANN-toolkit6.2.RC2Ascend-cann-toolkit开发套件包获取方式Ubuntu22.04 代码仓库地址&#xff1a; https://gitee.com/ascend/ascend_community_projects/tree/31…

01_原理-事件循环

01_原理-事件循环 文章目录 01_原理-事件循环一、浏览器的进程模型①&#xff1a;何为进程&#xff1f;②&#xff1a;何为线程&#xff1f;③&#xff1a;浏览器有哪些进程和线程&#xff1f; 二、渲染主线程是如何工作的&#xff1f;三、若干解释①&#xff1a;何为异步&…

不展现报表直接打印

不展现直接打印可以考虑这么几种方式&#xff1a;1、如果使用自带 demo 下的 jsp&#xff0c;可以把展现报表的 div 设置为隐藏&#xff0c;点击打印按钮可以打印&#xff1b;如果按钮都不想点&#xff0c;看下 toolbar.jsp 内打印按钮的 js 函数&#xff0c;在 jsp 末尾调用一…

LaTeX引文.bib方式插入报错 misplaced alignment tab character \end

写latex报了个莫名的错误&#xff0c;找了好久才找到原因。 参考文章 简单记录一下 在LaTeX中&符号有特殊含义&#xff0c;不能直接写。 直接复制生成的bibtex可能会有&&#xff0c;这种情况下可能会报错。 解决方法就是在&符号前面加一个斜杠\一定删除之前编译产生…

量子计算突破云渲染资源调度!真机测试完整报告公开!

​摘要&#xff1a;在影视领域中&#xff0c;经常会涉及大量的视频图像渲染工作&#xff0c;而往往在这种大规模、动态渲染场景下&#xff0c;普遍存在着冗余渲染现象。究其原因在于大规模的图像渲染通常要求在短时间内做出渲染任务的算力分配决策&#xff0c;而经典计算机无法…

【周报2023-11-24】

周报2023-11-24 本周主要工作下周工作计划 本周主要工作 本周的话一个主要工作有&#xff1a; 前后端进行联调接口&#xff1a; 那么目前为止的话&#xff0c;已经调通的接口 可以使用的是个人中心 历史生成的接口 选择新模板 新模板详情 ps: 下周工作计划 主要的话就是将…

金风玉露一相逢|实在智能联手浪潮信息合力致新生成式AI产业生态

近日&#xff0c;实在智能正式加入浪潮信息元脑生态AIStore。 实在智能是一家基于AGI大模型超自动化技术&#xff0c;领跑人机协同时代的人工智能科技公司&#xff0c;以其自研垂直的“TARS&#xff08;塔斯&#xff09;大语言模型”技术、实在RPA Agent智能体数字员工产品和超…

PSP - 蛋白质真实长序列查找 PDB 结构短序列的算法

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/134599076 在蛋白质结构预测的过程中&#xff0c;输入一般是蛋白质序列(长序列)&#xff0c;预测出 PDB 三维结构&#xff0c;再和 Ground Truth …

Android:控制按键灯亮灭【button-backlight】

/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java 1.导包 import java.io.DataOutputStream; import java.io.FileOutputStream; Handler mHandler3; 2.新建handler对象 public void init(Context context, IWindowManager windowMan…

制作linux deb安装包

dpkg 命令命令详解 dpkg -i手动安装软件包(这个命令并不能解决软件包之前的依赖性问题),如果在安装某一个软件包的时候遇到了软件依赖的问题,可以用apt-get -f install在解决信赖性这个问题.     dpkg --info “软件包名” --列出软件包解包后的包名称. dpkg -l–列出当前…

java 基础面试题——问题+答案——第1期

一、问题 在Java基础面试中&#xff0c;面试官可能会问及一系列基础知识&#xff0c;以确保对Java语言的核心概念和基本特性有清晰的理解。以下是一些可能的问题&#xff1a; Java基础&#xff1a; 解释Java的基本特性。什么是Java虚拟机&#xff08;JVM&#xff09;&#xff…

2024深圳电子展,加快粤港澳电子信息发展,重点打造“湾区经济”

在“十四五”期间&#xff0c;中国电子信息产业面临着新形势和新特点。随着国家对5G、人工智能、工业互联网、物联网等“新基建”的加速推进&#xff0c;以及形成“双循环”新格局的形势&#xff0c;新型显示、集成电路等产业正在加速向国内转移。这一过程不仅带来了新的应用前…

主从复制读写分离?

主从复制和读写分离是常见的数据库架构策略&#xff0c;它们可以提高系统的性能和可靠性。下面是一个简单的实现方法&#xff1a; 主从复制&#xff1a; 配置主数据库&#xff1a;在主数据库上启用二进制日志&#xff08;binary log&#xff09;&#xff0c;用于记录所有修改数…