今天,我有一个采访上,我问候选人很平常和基本的问题有关的区别Thread.sleep()和Object.wait().我希望他回答类似这样的事情,但他说这些方法基本上都是一样的,很可能Thread.sleep是Object.wait()在里面使用,但sleep本身并不需要外部锁定.这不是一个正确的答案,因为在JDK 1.6中,此方法具有以下签名.
public static native void sleep(long millis) throws InterruptedException;
Run Code Online (Sandbox Code Playgroud)
但我的第二个想法是,这不是那么荒谬.可以使用定时等待来实现相同的效果.看一下下面的代码片段:
public class Thread implements Runnable {
private final Object sleepLock = new Object();
// other implementation details are skipped
public static void sleep(long millis) throws InterruptedException {
synchronized (getCurrentThread().sleepLock){
getCurrentThread().sleepLock.wait(millis);
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,sleepLock是一个特别用于sleep方法内同步块的对象.我假设Sun/Oracle工程师知道Occam的剃须刀,因此sleep本地实现是故意的,所以我的问题是为什么它使用本机调用.
我想出的唯一想法是假设有人可能会找到有用的调用Thread.sleep(0).根据这篇文章对调度程序管理有意义:
这具有清除当前线程的量子并将其置于队列末尾以获得其优先级的特殊效果.换句话说,所有具有相同优先级的可运行线程(以及具有更高优先级的线程)将有机会在下一个给定CPU时间产生的线程之前运行.
所以一个synchronized块会带来不必要的开销.
您是否知道在Thread.sleep()实施中不使用定时等待的任何其他原因?
假设我们有非常简单的Java类MyClass.
public class MyClass {
private int number;
public MyClass(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
Run Code Online (Sandbox Code Playgroud)
构造具有某种状态的线程安全Java类有三种方法:
让它真正不变
public class MyClass {
private final int number;
public MyClass(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
}
Run Code Online (Sandbox Code Playgroud)制作场地number volatile.
public class MyClass {
private volatile int number;
public MyClass(int number) {
this.number = number; …Run Code Online (Sandbox Code Playgroud)假设我有以下Spring配置(Spring的版本是3.0.3):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="theFactoryBean" class="wax.MyFactoryBean"/>
<bean id="factoryBeanUser" class="wax.FactoryBeanUser">
<!-- what should be placed here?-->
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
我有FactoryBean实现的实例和一些其他实例.我需要Spring注入其他实例FactoryBean,而不是它生成的对象.
有两种可能的方法来解决它.
第一个,显而易见且有故障:
<bean id="factoryBeanUser" class="wax.FactoryBeanUser">
<property name="myFactoryBean" ref="&theFactoryBean"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
使用此配置,Spring会在启动时抛出异常:
[skipped irrelevant part]
Caused by: org.xml.sax.SAXParseException: The reference to entity "theFactoryBean" must end with the ';' delimiter.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:174)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:388)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1414)
Run Code Online (Sandbox Code Playgroud)
我找到了这个解决方案Spring:获取FactoryBean对象而不是FactoryBean.getObject(),这个问题得到了回答,有四个人投了赞成票.所以我假设这个解决方案可能有效,但目前我的代码中有问题.
第二个,工作但很尴尬:
public class FactoryBeanUser implements ApplicationContextAware{
private MyFactoryBean myFactoryBean;
public void setApplicationContext(ApplicationContext applicationContext) throws …Run Code Online (Sandbox Code Playgroud) @BeanSpring 3.0中有一个注释.它允许直接在Java代码中定义Spring bean.在浏览Spring引用时,我发现了两种使用此注释的不同方法 - 使用带有注释的内部类@Configuration和没有此注释的内部类.
本节包含以下代码:
@Component
public class FactoryMethodComponent {
@Bean @Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
// omitted irrelevant method
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们可以看到一段非常相似的代码,但现在@Configuration就在这里:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
Run Code Online (Sandbox Code Playgroud)
以前的参考部分包含以下解释:
Spring组件中的@Bean方法的处理方式与Spring @Configuration类中的对应方式不同.不同之处在于,使用CGLIB不会增强@Component类来拦截方法和字段的调用.CGLIB代理是调用@Configuration类@Bean方法中的方法或字段创建对协作对象的bean元数据引用的方法.使用普通的Java语义不会调用方法.相反,在@Component类@Bean方法中调用方法或字段具有标准Java语义.
但CGLIB是应用程序开发人员不应该意识到的一种内部东西(当然,在理想的世界中).据我所知,在两种情况下,Spring都会调用带有注释的方法@Bean来创建Spring bean,在这两种情况下,这些实例都会注入协作者.
所以我的问题是,作为两个案例之间的应用程序开发人员,我有什么不同?
假设我有两节课.每个类都有一个参数.第一类的参数限制为第二类,反之亦然.但还有一项要求.此参数还必须由类本身进行参数化.最好通过示例解释:
public class Class1<T extends Class2<Class1>> {
...
}
public class Class2<T extends Class1<Class2>> {
...
}
Run Code Online (Sandbox Code Playgroud)
但是,这种结构不起作用.编译告诉Type parameter Class2 is not within its bound.这是完全可以理解的,因为编译器无法解决这种无休止的递归.
但我想知道有什么优雅的方法可以通过通用获得想要的东西吗?