高并发复习
线程复习
一个进程可以有多个线程,就像迅雷。。。。
线程的状态: 新建 就绪 等待,运行 销毁
status: new runnable waiting terminited blocked
获得线程的四种方式
1: extends Thread run()重写
2: implement Runable start() 去调用run
4:threadPool
5:Time time = new Time();
time.schedule(Inner)
一般方法 用this上锁,静态方法用this.class上锁
ReentrantLock 锁是改变状态,state 里面用CAS操作,保证原子性
Synchronized
前提:jvm对象头分配的空间必须是8的倍数
对象 = 实例数据+ 对象头 +数据对齐
对象头: Mark Word (8byte)+ Class Metadata Address(4byte) 64位机器 12Byte 32位 4Byte
markOop.hpp
Synchornize锁:改变的是对象头里的锁标志位。两位二进制代表。
在Synchornize 的加持下,编译.class文件可以发现 他会存在一个monitorenter,monitorexit .是对锁的获得和释放的标志 。指令:javap -version xxx.class
ReentrantLock : 有改变内部state状态 CAS算法 保证状态正常
Callable 和runnable的区别
callable的时候是调用call()方法,但是call()方法 内容如下
/**
* A callable that runs given task and returns given result
*/
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
最终还是调用了run(),因为中间使用了一个适配器模式
而Runnable,则里面之后一个run方法
如果你单纯地调用run方法,那么他只会是一个任务,不会开启新的进程
但是如果你将runnable传递到Thread之后,再进行start,那么就会调用native方法,由系统去给你开辟一个新的进程。
java 的对象状态:
1:new出来 无状态
2:偏向锁
3:轻量锁
4:重量锁
5:gc标记
Thread的方法:
Thread.yield() 方法,使当前线程由执行状态,变成为就绪状态,让出cpu时间,在下一个线程执行时候,此线程有可能被执行,也有可能没有被执行。若线程带锁执行中,则继续执行
Thread.sleep():线程睡眠,无须唤醒 可以wait()作对比,sleep不释放锁,但是wait会释放. wait()线程想要重启则需要notify(),重新唤醒,去竞争cpu的时间片。
Thread.suspend(): suspend 不会释放锁 resume()
Thread.resume() :suspend 和resume 类似于wait和notify的关系,但是suspend 不会释放锁 。