-
Java 多线程引发的性能问题,怎么解决?
造成问题:
会消耗过多的CPU资源,如果可运行的线程数量多于可用处理器的数量,那么有线程将会被闲置。大量空闲的线程会占用许多内存,给垃圾回收器带来压力,而且大量的线程在竞争CPU资源时还将产生其他性能的开销。
解决:
使用线程池,是指管理一组同构工作线程的资源池。
- BIO、NIO分别是什么
阻塞(Block) / 非租塞(NonBlock)
阻塞:往往需要等待缓冲区中的数据准备好过后才处理其他的事情,否则一直等待在那里。
非阻塞:当我们的进程访问我们的数据缓冲区的时候,如果数据没有准备好则直接返回,不会等待。如果数据已经准备好,也直接返回。
阻塞和非阻塞关注的是程序在等待结果(消息,返回值)时的状态。
同步(Synchronization) / 异步(Asynchronization)
同步:是应用程序要直接参与IO读写的操作。
异步:所有的IO读写交给操作系统去处理,应用程序只需要等待通知。
同步阻塞I/O(BIO)
同步阻塞I/O,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制来改善。
同步非阻塞I/O(NIO)
同步非阻塞I/O,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求时才启动一个线程进行处理。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器。
NIO的3个核心概念:
- 缓冲区Buffer
在NIO中,所有的数据都是用缓冲区处理。IO是面向流的,NIO是面向缓冲区的。 - 通道Channel
Channel是一个通道,可以通过它读取和写入数据,他就像自来水管一样,网络数据通过Channel读取和写入。
通道和流不同之处在于通道是双向的,流只是在一个方向移动,而且通道可以用于读,写或者同时用于读写。 - 多路复用器Selector
Selector选择器可以监听多个Channel通道感兴趣的事情(read、write、accept(服务端接收)、connect,实现一个线程管理多个Channel,节省线程切换上下文的资源消耗。
参考:https://www.jianshu.com/p/91fe446aeb86
-
Oom 是否可以 try catch ?
在 try 语句中声明了很大的对象,导致 OOM,并且可以确认 OOM 是由 try 语句
中的对象声明导致的,那么在 catch 语句中,可以释放掉这些对象,解决 OOM
的问题,继续执行剩余语句。如果 OOM 的原因不是 try 语句中的
对象(比如内存泄漏),那么在 catch 语句中会继续抛出 OOM。
java switch对字符型支持是怎么实现的
对char类型的对比发现,是将char转成了Ascll码进行比较。
对字符串判断:
public static void main(String[] args) {
String str = "world";
switch (str) {
case "hello":
System.out.println("hello");
break;
case "world":
System.out.println("world");
break;
default:
break;
}
}
编译后的代码如下:
public static void main(String args[])
{
String str = "world";
String s;
switch((s = str).hashCode()) {
default:
break;
case 99162322:
if(s.equals("hello"))
System.out.println("hello");
break;
case 113318802:
if(s.equals("world"))
System.out.println("world");
break;
}
}
仔细看下可以发现,进行switch的实际是哈希值,然后通过使用equals方法比较进行安全检查,这个检查是必要的,因为哈希可能会发生碰撞。
总结一下我们可以发现,其实swich只支持一种数据类型,那就是整型,其他数据类型都是转换成整型之后在使用switch的。
参考:
https://blog.csdn.net/w372426096/article/details/77963685