1.多线程的创建方式有两种
a 实现Runnable的接口 实现他的run的方法 建议使用这种 因为接口可以实现多继承
b 集成Thread 的抽象类,重写父类的 run的方法。
2.run() 与start()的区别
调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。
把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由jvm的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void.
3.多线程的Synchronized
a Synchronized 需要锁住对象,不然的话还是会互斥。
b 静态方法和实例方法同步的话需要锁住 class本身,(静态方法需要同步只有锁住字节码的对象才可以 Object.class)
c 要用到共同数据,最好全部在同一个类中实现,既可以达到高内聚,也可以实现同步锁。
4.sleep和wait的区别
a sleep来自Thread类,和wait来自Object类。
b 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
c wait等待的线程可以用 notify 唤醒。这个可以用while 循环一起使用可以防止伪唤醒,因为有时候没用调用notify的时候也可以唤醒线程。
d 在wait()/notify()机制中,不要使用全局对象,字符串常量等。应该使用对应唯一的对象。
public void method(){
while(true){
wait();
........
notify();
}
}
5.线程共享变量
a ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。
b 也可以用HashMap类来实现这个功能,map.put(当前线程,需要该线程共享的值);
c ThreadLocal 的具体实现是 ThreadLocalMap 这个map的具体key是当前线程。该类的set方法与下面类似用来取值;
d 一个ThreadLocal只能放一个变量 如果有多个的话可以用一个实体封装。或者新建多个ThreadLocal对象;
public T get() {
//获取当前执行线程
Thread t = Thread.currentThread();
//取得当前线程的ThreadLocalMap实例
ThreadLocalMap map = getMap(t);
//如果map不为空,说明该线程已经有了一个ThreadLocalMap实例
if (map != null) {
//map中保存线程的所有的线程本地变量,我们要去查找当前线程本地变量
ThreadLocalMap.Entry e = map.getEntry(this);
//如果当前线程本地变量存在这个map中,则返回其对应的值
if (e != null)
return (T)e.value;
}
//如果map不存在或者map中不存在当前线程本地变量,返回初始值
return setInitialValue();
}
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;