java 多线程随记

来源:互联网 发布:杨千嬅 唱功 知乎 编辑:程序博客网 时间:2024/06/06 10:53

实现多线程的两种方式

1 继承 Thread 类,重写 run() 方法;
2 实现 Runnable 接口,重写 run() 方法;

线程五大状态

新建(new thread())

就绪(调用 start() 方法返回后)

运行(真正开始执行 run() 方法)

阻塞(sleep / io 阻塞/获取锁/等待某个触发条件等等)

死亡( run() 方法正常退出 / 未捕获异常终止了 run() 方法)

为了确定线程在当前是否存活着(要么是可运行的,要么是被阻塞了),需要使用 isAlive() 方法。如果是可运行或被阻塞,返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,返回false;


线程安全

线程的工作原理:jvm有一个main   memory,而每个线程有自己的 working   memory,一个线程对一个variable进行操作时,都要在自己的working   memory里面建立一个copy,操作完之后再写入main   memory。多个线程同时操作同一个variable,就可能会出现不可预知的结果。

实现方式:

1 给方法增加synchronized修饰符,方法可为静态或者非静态 但不能是抽象方法;

2 锁机制;

用 synchronized 的关键是建立一个 monitor(监听器),这个 monitor 可以是要修改的 variable(变量) 也可以其他你认为合适的 object(对象)比如method(方法),然后通过给这个monitor 加锁来实现线程安全,每个线程在获得这个锁之后,要执行完   load 到 working memory   ->   use&assign   ->   store到 main memory   的过程,才会释放它得到的锁。这样就实现了所谓的线程安全。


ReentrantLock 与 Synchronized 区别

1  如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断;如果使用 ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的     事情;

2  synchronized 是在 JVM 层面上实现的,不但可以通过一些监控工具监控 synchronized 的锁定,而且在代码执行时出现异常,JVM 会自动释放锁定,

    lock 是通过代码实现的,要保证锁定一定会被释放,就必须将 unLock() 放到 finally{} 中;

3  在资源竞争不是很激烈的情况下,Synchronized 的性能要优于 ReetrantLock,

    但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是 ReetrantLock 的性能能维持常态;