线程

来源:互联网 发布:怎么样开好淘宝店 编辑:程序博客网 时间:2024/06/07 16:15

这个文章主要讨论线程,线程的东西比较不好理解,我误打误撞得看了好久,也没看出个所以然来。
参考的有《java多线程编程核心技术》和 老马说编程的几篇博文


1.实现线程的方法有


继承Thread


实现Runnable接口,这种方法要好一些。因为java不允许多继承,但是能多实现呀。


实现callable接口,


用executor,它能一次生成多个线程


定时器Timer,每创建一个Timer相当于启动一个新的线程


2.线程的状态:


新生-------------------可运行------------------阻塞----------------------等待------------------死亡(现在没有死亡了,只有类似的一个中断)


new()                  start()                 sleep()                wait()、join()                  interrupt()
                       runnable状态           Blocked状态        waitting/timed_waitting状态       


线程可运行状态是start(),不是run(),run()只是个普通方法,start()里面有对run()的调用。
runnable状态:线程在运行或具备运行条件只是在等待操作系统调度
sleep()对锁没有任何要求,有没有锁都无所谓
wait()一定要有锁的情况下才能调用这个方法


3.线程间通信:


线程间的通信用的都是Object对象提供的方法。


wait()    等待,挂起。会释放共享资源的锁


notify()       通知,调用任意对象的这个方法会在线程中随机选一个解除阻塞,但要获得锁后才能继续执行。


notifyAll()    通知所有,解除那个对象所有被阻塞的线程。


这几个方法经常考,我要记住中文意思,来猜是线程的方法还是Object的方法,Object的能线程沟通通信,thread的只能控制它自己。


4.synchronized和java.util.concurrent.locks.lock和ReentrantLock有什么区别


lock是对synchronized的改进,从时间上就要晚很长时间。synchronized的弱点是有一些功能性的限制 —— 它无法中断一个正在等候获得锁的线程,也无法通过轮询得到锁,如果不想等下去,也就没法得到锁。同步还要求锁的释放只能在与获得锁所在的堆栈帧相同的堆栈帧中进行,多数情况下,这没问题(而且与异常处理交互得很好),但是,确实存在一些非块结构的锁定更合适的情况


其他的我就看不懂了。
由于synchronized是在JVM层面实现的,因此系统可以监控锁的释放与否,而ReentrantLock使用代码实现的,系统无法自动释放锁,需要在代码中finally子句中显式释放锁lock.unlock();
ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候


     线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定,


     如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断


     如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情


ReentrantReadWriteLock   
---------1> readLock().lock()读读共享,用它加锁后,2个线程能同时读取一个数据
---------2> writeLock().lock()写写排斥,用它加锁后,2个线程写数据的话就排队
---------3>把前2个同时使用就可以实现读排斥写,写排斥读


5.vilatile一个变量存在于多个CPU缓存中,可能会出现缓存不一致,如果CPU写数据时,发现它操作的是共享变量,会发信号通知其他CPU把该变量的缓存行置为无效状态,其他CPU读取这个变量时,发现这个变量的缓存行是无效的,就会从内存中重新读取。
6.timer 定时器
全程每看懂,定时器和多线程为什么还放在一起了


0 0