1、ThreadLocal:
线程局部变量。是一个泛型集合
作用:防止事务间同时存取时数据混乱
内部机制:
内部其实是个Map来保存数据。在使用ThreadLocal时只给出值,内部会自动使用当前线程做为键。
方法:
void set(T value):保存值
T get():获取值
void remove(): 删除值。
/**
* ThreadLocal对象的用法
*
*/
public class Demo1 {
@Test
public void fun1() {
final ThreadLocal<String> tl = new ThreadLocal<String>();
new Thread() {
public void run() {
tl.set("内部类存");
}
}.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(tl.get());
}
@Test
public void fun2() {
final Map<Thread, String> map = new HashMap<Thread, String>();
map.put(Thread.currentThread(), "hello");
System.out.println(map.get(Thread.currentThread()));
new Thread() {
public void run() {
System.out.println(Thread.currentThread().getName());
System.out.println(map.get(Thread.currentThread()));
}
}.start();
}
}
/**
* 线程集合内部
* 它的内部是一个Map,用线程做key,每个线程对应存取删功能。
* 内部有N个线程。
*
* @param <T>
*/
class TL<T> {
private Map<Thread, T> map = new HashMap<Thread, T>();
public void set(T data) {
map.put(Thread.currentThread(), data);
}
public T get() {
return map.get(Thread.currentThread());
}
public void remove() {
map.remove(Thread.currentThread());
}
}
/**
* ThreadLocal通常用在一个类的成员上
* 多个线程访问它时,每个线程都有自己的副本,互不干扰!
* Spring中把Connection放到了ThreadLocal中!
* 明天我们会再次修改JdbcUtils类!,给它添加一个ThreadLocal<Connection>
*
*/
class User {
private ThreadLocal<String> usernameTl = new ThreadLocal<String>();
}
2、增强对象的手段
1)继承
缺点: 增强内容是死的
被增强的对象也是死的。
会导致类的暴增。
2)装饰者模式:在原有对象上装饰。 (是你还有你,一切拜托你。)
增强内容是死的
3)动态代理:
被增强的对象可以切换:Service
增强的内容也可以切换:事务处理
装饰者模式:在原有对象上装饰。 (是你还有你,一切拜托你。)
增强内容是死的
被增强的对象可以任意。
咖啡 a = new 加糖();
咖啡 b = new 加盐(a); 得到加糖加奶的咖啡。
咖啡 c = new 加奶(b); 得到加糖、盐、奶的咖啡。
此模式多用于 Java API 中的 IO流
eg:
FileInputStream: 是节点流。 是和资源(磁盘文件)绑定在一起的
BufferedInputStream: 装饰流。 创建时需要一个底层对象,然后为底层对象创建缓冲区
做法:继承原有对象,提供构造方法。
1)使用中间者类继承原有对象类(被装饰),原有方法不变。
a.提供构造器,构造原有对象。
b.private 类 类名。
2)重写想要改变的方法。
3)new中间者对象,传参为原有对象。
装饰者模式
class MyConnection implements Connection {
private Connection con;
public MyConnection(Connection con){
this.con = con;
}
public Statement createStatement() {
return con.createStatement();
}
public void close(){
把当前连接归还给池!
}
}
Connection con = 通过四大参数创建连接对象!是由mysql提供的!
Connection con1 = new MyConnection(con);
con1.createStatement()
con.createStatement();
con1.close();
con.close();
class MyInputStream extends InputStream {
private InputStream in;
private int key;
public MyInputStream(InputStream in, int key){
this.in = in;
this.key = key;
}
@Override
public int read() throws IOException {
return this.in.read() - key;
}
}