自学内容网 自学内容网

每日一练,java03

题目

选自牛客网
1.下面关于JAVA的垃圾回收机制,正确的是( )
A.当调用“System.gc()”来强制回收时,系统会立即回收垃圾
B.垃圾回收不能确定具体的回收时间
C.程序可明确地标识某个局部变量的引用不再被使用
D.程序可以显式地立即释放对象占有的内存

正确答案:B
正确的描述是选项B:“垃圾回收不能确定具体的回收时间”。Java的垃圾回收机制是自动运行的,它负责回收不再使用的对象所占用的内存。然而,垃圾回收的具体触发时间和频率是不确定的,由垃圾回收器根据系统的运行状态自动决定。即使调用了System.gc()方法建议进行垃圾回收,也不能保证垃圾回收会立即执行,这只是一个建议,垃圾回收器可以选择忽略。因此,选项B是正确的。选项A和D的描述与Java垃圾回收机制的实际行为不符,而选项C描述的是可以通过将引用设为null来暗示对象不再使用,但这并不是强制垃圾回收,垃圾回收器仍然会根据自己的策略来决定何时回收这些对象。

2.java中Hashtable, Vector, TreeSet, LinkedList哪些线程是安全的?
A.Hashtable
B.Vector
C.TreeSet
D.LinkedList

正确答案:AB

在Java中,HashtableVector是早期设计的集合类,它们内部的方法是同步的,因此它们是线程安全的。这意味着它们可以在多线程环境中共享而不需要额外的同步措施。然而,TreeSetLinkedList并不提供内置的线程安全保障,它们的方法是非同步的,因此在多线程环境中共享时需要额外的同步控制,或者使用线程安全的包装类,如Collections.synchronizedSet()Collections.synchronizedList(),来包装这些集合,以提供线程安全性。

因此,正确答案是 A 和 B:HashtableVector是线程安全的集合类。


3.下面哪些写法能在 java8 中编译执行()

A.dir.listFiles((File f)->f.getName().endsWith(“.Java”));
B.dir.listFiles((File f)=>f.getName().endsWith(“.Java”));
C.dir.listFiles((_.getName().endsWith(“.Java”)));
D.dir.listFiles( f->f.getName().endsWith(“.Java”));

ad

  1. 形参列表

    • 形参列表定义了Lambda表达式接受的参数。参数类型可以被省略,Java编译器会根据上下文推断它们的类型。
    • 如果Lambda表达式只有一个参数,那么甚至可以省略圆括号。例如,(String s) -> s.length()可以简化为String s -> s.length()
  2. 箭头(→)

    • 箭头是Lambda表达式的固定组成部分,用于分隔形参列表和代码块。它表示从参数到执行代码的转换。
  3. 代码块

    • 代码块包含了Lambda表达式执行的逻辑。如果代码块仅包含一条语句,那么可以省略花括号。
    • 如果代码块中的语句是单一的返回语句,那么return关键字也可以被省略,Lambda表达式会自动返回这条语句的结果。

基于这些规则,选项A和D的Lambda表达式是正确的,它们遵循了正确的语法和结构,能够编译执行。例如:

  • 选项A:dir.listFiles((File f) -> f.getName().endsWith(".Java"));
  • 选项D:dir.listFiles(f -> f.getName().endsWith(".Java"));

这两个选项中,Lambda表达式接受一个File类型的参数,并返回一个布尔值,表示文件名是否以".Java"结尾,这符合listFiles方法需要的过滤器逻辑。


4.以下哪几种方式可用来实现线程间通知和唤醒:( )
A.Object.wait/notify/notifyAll
B.ReentrantLock.wait/notify/notifyAll
C.Condition.await/signal/signalAll
D.Thread.wait/notify/notifyAll
正确答案:AC

wait()、notify()和notifyAll()方法的特性和使用场景

wait()notify()notifyAll()是Java中用于线程间通信的内置方法,它们定义在Object类中,因此适用于所有Java对象。这些方法与同步机制紧密相关,它们必须在同步块或同步方法中被调用,以确保线程安全。

wait() 方法
  • wait()方法允许一个线程放弃对象的锁,并等待直到另一个线程通知该对象锁已被释放。
  • 当一个线程调用对象的wait()方法时,它会立即释放该对象的锁,并进入到该对象的等待集合(wait set)中。
  • 调用wait()方法必须在同步控制块或同步方法中进行,以避免违反锁的独占性。
notify() 方法
  • notify()方法用于唤醒在同一个对象的等待集合中等待的单个线程。
  • 调用notify()方法的线程必须持有该对象的锁,但在调用后会立即释放锁,使得等待集合中的一个线程可以尝试重新获取锁。
  • 被唤醒的线程将继续执行,但它能否成功获取锁取决于锁的可用性和其他线程的竞争。
notifyAll() 方法
  • notifyAll()方法用于唤醒在同一个对象的等待集合中等待的所有线程。
  • notify()方法类似,调用notifyAll()的线程必须持有该对象的锁,并在调用后释放锁。
  • 所有等待集合中的线程都会被唤醒,但它们仍然需要竞争锁以继续执行。
使用场景
  • wait()notify()notifyAll()通常用于实现生产者-消费者问题、读写锁、条件变量等多线程同步场景。
  • 这些方法可以帮助线程在某个条件尚未满足时暂停执行,并在条件满足时恢复执行,从而实现线程间的协作。

注意事项

  • 在使用wait()notify()notifyAll()时,应当小心避免死锁和竞态条件。
  • 通常建议在等待条件前使用循环检查来确认条件是否真的已经满足,以防止虚假唤醒(spurious wakeup)。
  • 这些方法在多线程编程中是非常强大的工具,但也需要谨慎使用,以确保程序的正确性和性能。

3.以下代码输出的是:
public class SendValue{
public String str=“6”;
public static void main(String[] args) {
SendValue sv=new SendValue();
sv.change(sv.str);
System.out.println(sv.str);
}
public void change(String str) {
str=“10”;
}
}

A.6
B.10
C.都不对
D.16

正确答案:A
代码中的change方法接受一个String类型的参数str,并将其修改为"10"。然而,这个方法内部的str变量是局部变量,它与类的成员变量str是两个不同的引用。因此,即使局部变量str的值被修改,类的成员变量str的值仍然保持不变,其值为"6"。所以,当打印出sv.str的值时,输出结果是6。这说明Java中字符串是不可变的,修改字符串实质上是创建了一个新的字符串对象,而不会改变原始字符串对象的值。因此,正确答案是A.6。


原文地址:https://blog.csdn.net/m0_67187271/article/details/140661593

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!