一课掌握Java并发编程精髓(完结13章)

huiguniang2008 · · 534 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

一课掌握Java并发编程精髓(完结13章) 分享一套Java课程——一课掌握Java并发编程精髓(完结13章),附源码+PDF课件下载。 并发编程 1.多线程 Java 是最先支持多线程的开发的语言之一,Java 从一开始就支持了多线程能力。由于现在的 CPU 已经多是多核处理器了,是可以同时执行多个线程的。 多线程优点 多线程技术使程序的响应速度更快 ,可以在进行其它工作的同时一直处于活动状态,程序性能得到提升。 性能提升的本质 就是榨取硬件的剩余价值(硬件利用率)。 并行与并发 单核 cpu 下,线程实际是串行执行的。操作系统中有一个组件叫做任务调度器,将 cpu 的时间片,分给不同的线程使用,只是由于 cpu 在线程间(时间片很短)的切换非常快,人类感觉是同时运行的。 总结为一句话就是:微观串行,宏观并行,一般会将这种线程轮流使用 cpu的做法称为并发,concurrent。 Java 内存模型(Java Memory Model,JMM)规范了 Java 虚拟机与计算机内存是如何协同工作的。Java 虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一个内存模型——又称为 Java 内存模型。 JVM 主内存与工作内存 Java 内存模型中规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。 这里的工作内存是 JMM 的一个抽象概念,也叫本地内存,其存储了该线程读/写共享变量的副本。 线程常用的方法 start() : 启动当前线程, 调用当前线程的run()方法。 run() : 通常需要重写Thread类中的此方法, 将创建的线程要执行的操作声明在此方法中。 currentThread() : 静态方法, 返回当前代码执行的线程。 getName() : 获取当前线程的名字。 setName() : 设置当前线程的名字。 yield() : 释放当前CPU的执行权。 join() : 在线程a中调用线程b的join(), 此时线程a进入阻塞状态, 知道线程b完全执行完以后, 线程a才结束阻塞状态。 stop() : 已过时. 当执行此方法时,强制结束当前线程. sleep(long militime) : 让线程睡眠指定的毫秒数,在指定时间内,线程是阻塞状态。 isAlive() :判断当前线程是否存活。 wait()和 sleep()方法有什么区别 sleep 方法和 wait 方法都可以用来放弃 CPU 一定的时间,不同点在于如果线程持有某个对象的监视器,sleep 方法不会放弃这个对象的监视器,wait 方法会放弃这个对象的监视器。 wait需要等待唤醒,而sleep睡眠一定时间之后自动苏醒。 继承Thread类 重写run方法 启动线程是调用start方法,这样会创建一个新的线程,并执行线程的任务。 如果直接调用run方法,这样会让当前线程执行run方法中的业务逻辑。 public class MiTest { public static void main(String[] args) { MyJob t1 = new MyJob(); t1.start(); for (int i = 0; i < 100; i++) { System.out.println("main:" + i); } } } class MyJob extends Thread{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("MyJob:" + i); } } } 实现Runnable接口 重写run方法 public class MiTest { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread t1 = new Thread(myRunnable); t1.start(); for (int i = 0; i < 1000; i++) { System.out.println("main:" + i); } } } class MyRunnable implements Runnable{ @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("MyRunnable:" + i); } } } sleep有两个方法重载: 第一个就是native修饰的,让线程转为等待状态的效果 第二个是可以传入毫秒和一个纳秒的方法(如果纳秒值大于等于0.5毫秒,就给休眠的毫秒值+1。如果传入的毫秒值是0,纳秒值不为0,就休眠1毫秒) sleep会抛出一个InterruptedException public static void main(String[] args) throws InterruptedException { System.out.println(System.currentTimeMillis()); Thread.sleep(1000); System.out.println(System.currentTimeMillis()); } 缓存一致性(MESI) 用于保证多个 CPU cache 之间缓存共享数据的一致 M-modified被修改 该缓存行只被缓存在该 CPU 的缓存中,并且是被修改过的,与主存中数据是不一致的,需在未来某个时间点写回主存,该时间是允许在其他CPU 读取主存中相应的内存之前,当这里的值被写入主存之后,该缓存行状态变为 E E-exclusive独享 缓存行只被缓存在该 CPU 的缓存中,未被修改过,与主存中数据一致 可在任何时刻当被其他 CPU读取该内存时变成 S 态,被修改时变为 M态 S-shared共享 该缓存行可被多个 CPU 缓存,与主存中数据一致 I-invalid无效 线程安全性 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的 synchronized 修正计数类方法 修饰类:括号括起来的部分,作用于所有对象 子类继承父类的被 synchronized 修饰方法时,是没有 synchronized 修饰的!!! Lock: 依赖特殊的 CPU 指令,代码实现 ![QQ截图20231220144119.png](https://static.golangjob.cn/231220/0472ef9629b9f7e716623851a107c083.png)

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

534 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传