volatile 关键字volatile 是一个特殊的修饰符,只有成员变量才能使用它 。在Java并发程序缺少同步类的情况下,多线程对成员变量的操作对其它线程是透明的 。volatile 变量可以保证下一个读取操作会在前一个写操作之后发生 。线程都会直接从内存中读取该变量并且不缓存它 。这就确保了线程读取到的变量是同内存中是一致的 。
ThreadLocal 变量ThreadLocal 是Java里一种特殊的变量 。每个线程都有一个 ThreadLocal 就是每个线程都拥有了自己独立的一个变量,竞争条件被彻底消除了 。如果为每个线程提供一个自己独有的变量拷贝,将大大提高效率 。首先,通过复用减少了代价高昂的对象的创建个数 。其次,你在没有使用高代价的同步或者不变性的情况下获得了线程安全 。
join() 方法join() 方法定义在 Thread 类中,所以调用者必须是一个线程,join() 方法主要是让调用该方法的 Thread 完成 run() 方法里面的东西后,再执行 join() 方法后面的代码,看下下面的"意思"代码:
Thread t1 = new Thread(计数线程一);Thread t2 = new Thread(计数线程二);t1.start();t1.join(); // 等待计数线程一执行完成,再执行计数线程二t2.start();启动 t1 后,调用了 join() 方法,直到 t1 的计数任务结束,才轮到 t2 启动,然后 t2 才开始计数任务,两个线程是按着严格的顺序来执行的 。如果 t2 的执行需要依赖于 t1 中的完整数据的时候,这种方法就可以很好的确保两个线程的同步性 。
Thread.yield() 方法Thread.sleep(long time):线程暂时终止执行(睡眠)一定的时间 。Thread.yield():线程放弃运行,将CPU的控制权让出 。
这两个方法都会将当前运行线程的CPU控制权让出来,但 sleep() 方法在指定的睡眠时间内一定不会再得到运行机会,直到它的睡眠时间完成;而 yield() 方法让出控制权后,还有可能马上被系统的调度机制选中来运行,比如,执行yield()方法的线程优先级高于其他的线程,那么这个线程即使执行了 yield() 方法也可能不能起到让出CPU控制权的效果,因为它让出控制权后,进入排队队列,调度机制将从等待运行的线程队列中选出一个等级最高的线程来运行,那么它又(很可能)被选中来运行 。
扩展线程调度策略
(1) 抢占式调度策略
Java运行时系统的线程调度算法是抢占式的 。Java运行时系统支持一种简单的固定优先级的调度算法 。如果一个优先级比其他任何处于可运行状态的线程都高的线程进入就绪状态,那么运行时系统就会选择该线程运行 。新的优先级较高的线程抢占了其他线程 。但是Java运行时系统并不抢占同优先级的线程 。换句话说,Java运行时系统不是分时的 。然而,基于Java Thread类的实现系统可能是支持分时的,因此编写代码时不要依赖分时 。当系统中的处于就绪状态的线程都具有相同优先级时,线程调度程序采用一种简单的、非抢占式的轮转的调度顺序 。
(2) 时间片轮转调度策略
有些系统的线程调度采用时间片轮转调度策略 。这种调度策略是从所有处于就绪状态的线程中选择优先级最高的线程分配一定的CPU时间运行 。该时间过后再选择其他线程运行 。只有当线程运行结束、放弃(yield)CPU或由于某种原因进入阻塞状态,低优先级的线程才有机会执行 。如果有两个优先级相同的线程都在等待CPU,则调度程序以轮转的方式选择运行的线程 。
以上把这些技术点总结出来,后面我会把多线程这块的示例代码更新到 《个人学习项目DroidStudy》,感谢您的关注 。
● 线程池创建多个线程不光麻烦而且相对影响系统性能,接下来让我看看使用线程池来操作多线程 。我把自己的 《个人学习项目DroidStudy》 中线程池转成一个 gif 效果图,大家可以实际把玩下去感受线程池的原理,有兴趣的同学也可以先 star 下,我会在接下来的几个月把这个学习的Demo工程完善好 。

文章插图
线程池.gif
线程池的优点1)避免线程的创建和销毁带来的性能开销 。2)避免大量的线程间因互相抢占系统资源导致的阻塞现象 。3}能够对线程进行简单的管理并提供定时执行、间隔执行等功能 。
再撸一撸概念Java里面线程池的顶级接口是 Executor,不过真正的线程池接口是 ExecutorService,ExecutorService 的默认实现是 ThreadPoolExecutor;普通类 Executors 里面调用的就是 ThreadPoolExecutor 。
照例看一下各个接口的源码:
public interface Executor {void execute(Runnable command);}public interface ExecutorService extends Executor {void shutdown();List<Runnable> shutdownNow();boolean isShutdown();boolean isTerminated();<T> Future<T> submit(Callable<T> task);<T> Future<T> submit(Runnable task, T result);Future<?> submit(Runnable task);...}public class Executors {public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}...}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 绿色环保家具排行榜
- 北京环球度假区怎么去?地铁、驾车都方便,小编带你走一趟
- 什么,葡萄酒还有欧盟有机认证?
- 舌头|火腿肠吃出尖锐异物、舌头划烂出血?双汇:需要核实
- 古丈县、舌尖山水,古丈毛尖
- 淘宝、抖音、快手的流量运营逻辑!
- 细谈8种架构设计模式及其优缺点
- 常见web安全问题,SQL注入、XSS、CSRF,基本原理以及如何防御
- 一加Ace|一加官宣云耳Z2、Buds N两款耳机新品:21日与Ace同步发布
- 孕妇可以喝茶吗? 过多、过浓或影响胎儿发育
