浏览 607 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2023-12-20
网盘地址:https://pan.baidu.com/s/15RSGSAItdF2cqtYVWSexMw 提取码: c5jx 腾讯微云下载地址:https://share.weiyun.com/6RzGbzZc 密码:bi833u 分享一套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 指令,代码实现 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |