Android开发中的常见字符串问题(中高级)

1、String 是 java 中的基本数据类型吗?是可变的吗?是线程安全的吗?

String 不是基本数据类型,java 中的基本数据类型是:byte、short、int、long、char、float、double、boolean。

String 是不可变类,一旦创建了 String 对象,我们就无法改变它的值,因此,它是线程安全的,可以安全地用于多线程环境中。

2、为什么要设计成不可变的呢?

String 设计为不可变的原因有如下 3 点:

  • 安全:由于 String 广泛用于 java 类中的参数,所以安全是非常重要的考虑点,包括线程安全,打开文件,存储数据密码等等。
  • 效率:String 的不变性保证哈希码始终如一,所以在用于 HashMap 等数据结构的时候就不需要重新计算哈希码,提高效率。
  • 空间:因为不同的字符串变量可以引用池中的相同字符串,所以可以在java 运行时节省大量的 java 堆空间,如果字符串是可变的话,任何一个变量的值改变,就会反射到其他变量,那字符串池也就没有任何意义了。

3、如果 String 是不可变的,那我们平时赋值的是改了什么呢?

平时使用双引号方式赋值的时候其实是返回的字符串引用,并不是改变了这个字符串对象。

4、String 有哪些创建方式?它们在 JVM 的存储方式是相同吗?

String 常见的创建方式有两种:

  • 第一种:String s1 = “Java”
    s1 会先去字符串常量池中找字符串 "Java",如果有相同的字符则直接返回字符串引用,如果没有此字符串则会先在常量池中创建此字符串,然后再返字符串引用。

  • 第二种:String s2 = new String("Java")
    s2 是直接在堆上创建一个变量对象,但不存储到字符串池,调用 intern 方法才会把此字符串保存到常量池中。

5、简单讲讲 String,StringBuffer,StringBuilder 的区别?

String 是不可变类,每当我们对 String 进行操作的时候,总是会创建新的字符串。操作 String 很耗资源,所以 Java 提供了两个工具类 StringBuffer 和 StringBuilder 来操作 String。

StringBuffer 和 StringBuilder 是可变类,StringBuffer 是线程安全的,StringBuilder 不是线程安全的。所以在多线程对同一个字符串操作的时候,我们应该选择用 StringBuffer,由于不需要处理多线程的情况,StringBuilder 的效率比 StringBuffer 要高。

6、如何停止一个线程?

终止线程有 3 种方式:

1、使用 stop 方法强行终止线程

但是这种方式是不安全的,主要有两点原因:

  • thread.stop() 调用之后,创建子线程的线程就会抛出 ThreadDeathError 的错误,并且会释放子线程持有的所有锁
  • 一个线程被 stop 停止并释放锁,其写入的内存数据写到一半没有被清除,但此时另一个线程得到锁发现此内存区块的数据是异常的

2、使用 interrupt() 方法中断线程

这种方式的缺点在于线程不一定会终止。

Thread::Interrupted() 相比 Thread::IsInterrupted() 方法在native 底层仅仅多调用了一行 SetInterruptedLocked(false) 来清空当前的中断状态,其内部使用了 wait_mutex_ 互斥加锁来保证线程安全。

3、使用 volatile boolean 变量退出标志

这种方式能够使线程正常退出,也就是当 run 方法完成后线程终止。

因为 interrupt 是系统方法,并且使用了 JNI 调用、内部实现采用了加锁,且它的触发方式是采取了抛异常的方式,所以建议需要支持系统方法时采用中断,其它情况用 volatile boolean 标志位即可。

4、那如何终止线程池呢?

终止线程池有两种方式:

ExecutorService 线程池提供了 shutdown 和 shutdownNow 这样的生命周期方法来关闭线程池自身以及它所拥有的线程。

  • shutdown 关闭线程池:线程池不会立即退出,不再接受新的任务,但可以继续执行池子中已经添加到等待队列的任务。
  • shutdownNow 关闭线程池并中断任务:线程池不会立即退出,不再接受新的任务,也不再处理等待队列中的任务,并试图使用 Thread.interrupt() 去打断正在执行的任务。但是我们都知道,如果线程中没有 sleep、wait、Condition、定时锁等应用,interrupt() 是无法中断当前线程的,所以,ShutdownNow() 并不代表线程池就一定能立即退出,它可能必须要等待所有正在执行的任务都执行完成了才能退出。
#Android##安卓工程师##android#
Android技术 文章被收录于专栏

热门Android技术学习

全部评论
学到到了终止线程的方法
点赞 回复 分享
发布于 2022-08-29 16:11 陕西

相关推荐

02-23 00:10
湖南大学 C++
点赞 评论 收藏
分享
请问三天没被捞是不是就是挂了,流程也结束了
我真的是钛材料:我也还没捞,但是还在筛选中,什么时候是个头啊
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务