1.编写Java程序时,如何在Java中创建死锁并修复它?
2.如何使用双重检查锁定在Java中创建线程安全的单例?
3.为什么char数组比Java中的String更适合存储密码?
4.为什么String在Java中是不可变的?
5.为什么Java不支持运算符重载?
6.为什么等待和通知是在Object类而不是Thread中声明的?
加入阿里云钉钉群享福利:每周技术直播,定期群内有奖活动、大咖问答
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Java中创建死锁并修复它:
创建死锁的示例代码如下:
public class DeadLockDemo {
private static Object resource1 = new Object();
private static Object resource2 = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + " got resource1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource2) {
System.out.println(Thread.currentThread() + " got resource2");
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + " got resource2");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource1) {
System.out.println(Thread.currentThread() + " got resource1");
}
}
});
thread1.start();
thread2.start();
}
}
修复死锁的方法是确保线程获取资源的顺序一致,例如,都先获取resource1
再获取resource2
。
使用双重检查锁定创建线程安全的单例:
双重检查锁定是一种常用的优化手段,用于减少同步开销,同时保证线程安全。示例代码如下:
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
volatile
关键字确保了多线程环境下实例变量被正确地初始化。
char数组比String更适合存储密码:
原因在于安全性。String对象在Java中是不可变的,一旦创建就无法修改,这意味着密码作为字符串存在内存中可能会留下痕迹,容易受到内存分析工具的攻击。而使用char数组可以手动覆盖敏感信息,比如在验证密码后将数组中的字符置为默认值,从而提高安全性。
String在Java中是不可变的原因:
String设计成不可变是为了实现线程安全、高效地共享和作为哈希码的键(如HashMap的键)。不可变性使得字符串池成为可能,减少了内存消耗,并且允许类库方法不必担心字符串内容被意外改变。
Java不支持运算符重载的原因:
Java设计者选择不支持运算符重载主要是为了保持语言的简单性和易读性。避免运算符重载可能导致的潜在滥用和理解上的复杂性,使得代码更易于阅读和维护。
等待和通知是在Object类而不是Thread中声明的原因:
等待(wait)、通知(notify/notifyAll)方法与特定的对象监视器(即锁)相关联,而不是与线程本身关联。这些操作都是基于对象的,因为它们涉及到对象的状态和多个线程对该状态的访问控制。因此,将它们放在Object类中意味着任何对象都可以用作锁,进而实现线程间的同步。这符合面向对象编程的原则,即行为与数据紧密耦合。