Filter base class that aims to guarantee a single execution per request dispatch, on any servlet container. It provides a doFilterInternal method with HttpServletRequest and HttpServletResponse arguments.
As of Servlet 3.0, a filter may be invoked as part of a REQUEST or ASYNC dispatches that occur in separate threads. A filter can be configured in web.xml whether it should be involved in async dispatches. However, in some cases servlet containers assume different default configuration. Therefore sub-classes can override the method shouldNotFilterAsyncDispatch() to declare statically if they should indeed be invoked, once, during both types of dispatches in order to provide thread initialization, logging, security, and so on. This mechanism complements and does not replace the need to configure a filter in web.xml with dispatcher types.
final URL resource2 = Thread.currentThread().getContextClassLoader().getResource("./root.properties"); System.err.println(resource2);
这样是可以成功查找。
Class#getResouce
1 2 3 4 5 6 7 8 9
public InputStream getResourceAsStream(String name) { name = resolveName(name); ClassLoader cl = getClassLoader0(); if (cl==null) { // A system class. return ClassLoader.getSystemResourceAsStream(name); } return cl.getResourceAsStream(name); }
public class Singleton { static Singleton instance; static Singleton getInstance(){ if (instance == null) { synchronized(Singleton.class) { if (instance == null) instance = new Singleton(); } } return instance; } }
new Singleton()这句话感觉是
分配一块内存M
在内存M上初始化Singleton对象
然后M的地址赋值给instance变量
实际执行路径却是:
分配一块内存M
将M的地址赋值给instance变量
最后在内存M上初始化Singleton对象
JMM
如何解决上述的三大问题,JSR-133定义了内存模型JMM
A memory model describes, given a program and an execution trace of that program, whether the execution trace is a legal execution of the program. For the Java programming language, the memory model works by examining each read in an execution trace and checking that the write observed by that read is valid according to certain rules.
Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second. It should be stressed that a happens-before relationship between two actions does not imply that those actions must occur in that order in a Java platform implementation. The happens-before relation mostly stresses orderings between two actions that conflict with each other, and defines when data races take place.
从定义中可以看出两点:
1、the first is visible to and ordered before the second
A and B are locations in memory. However the operation B+1 does not happen in memory, it happens in the CPU. Specifically, the author is describing these two operations.
A = B + 1 (1)
A1 - The value in memory location B (0) is loaded into a CPU register
A2 - The CPU register is incremented by 1
A3 - The value in the CPU register (1) is written to memory location A
B = 1 (2)
B1 - The value 1 is written to memory location B
Happens-Before requires that the read of B (step A1) happens before the write of B (step B1). However, the rest of the operations have no interdependence and can be reordered without affecting the result. Any of these sequences will produce the same outcome