在实践中发现,多线程的问题,再怎么强调也不过分。 于公可以装逼,于私可产生极大的乐趣! 我就厚着脸皮参照网上的帖子,进行练习,并做一下笔记吧。
线程外实现 java线程同步的方式:
1.synchronized关键字。 ( 修饰方法或者方法块。好像不能直接修饰属性) (java的每个对象都有一个内置锁,用 该关键字作用于 静态变量时,为类锁,否则为对象锁),它可作用于方法,也可作用于方法块,使用方式: synchronized(object){}; v
2.volatile针对虚拟机(告诉虚拟机,该值可能不安全,每次都需重新计算)的配合实现,用于修饰属性(好像),它不能修饰final域。
3.使用concurrent包提供的重入锁实现同步: ReentrantLock类(使用时,应该也要针对具体的内容,需要互斥同步的代码块,应该具有同一把锁对象。 注意,该包下还有一个读写锁:ReadWriteLock(接口))。通常需要在finally代码块中释放锁,以免造成死锁。
4.ThreadLocal管理局部变量。(每个线程建立一个该变量的副本,各线程的变量副本之间相互独立)。 关键方法: get(),initialValue(),set(T value); ( 同步机制是 时间换空间,ThreadLocal是空间换时间,因为中途设计到是否阻塞的问题)。 用法示例:
ThreadLocal<T> tl = new ThreadLocal<T>(){ @Override T initialValue(){return t;}}; 其余所有操作则针对 tl进行。 它此时为 变量的线程局部副本。
5.阻塞队列实现同步。位于java.util.concurrent包下的 LinkedBlockingQueue<E> 是先进先出的队列实现的。 它不是基于底层实现。主要方法:put(E e),sizie(),take();
6.使用原子变量。java.util.concurrent.atomic包中提供了原子类型变量的工具类。 (原子操作主要包括了 引用变量和大多数原始变量(double外)的读写操作).
最后贴一下1.8的concurrent包的代码结构:
线程角度实现线程同步的方法:
1.使用wait/nofity机制: Object对象有三个方法: wait,notify,nofityAll. wait,notify都包含对 对象锁 的操作,也就是必须在同步块中调用。
2.使用 yield()方式,让出执行权给同等优先级的线程; 仅能使线程状态在 运行 与 可运行值之间转换。
3.使用join()方式, 使得等待特定线程执行完毕后执行;此时有一个线程是阻塞状态。 参考地址。
【转自:香港服务器 https://www.68idc.cn提供,感谢支持】