标签:
1.多线程
1.1.进程与线程
? 进程就是一个运行中的程序。
? 一个进程中可以有多个线程,线程是CPU调度和分派的基本单位。我们可以理解为线程就是程序运行中的一条路径。
1.2.多线程的创建及使用
1.2.1.创建
自定义一个类继承Thread类或实现Runnable接口
1.2.2:两种创建多线程的区别
继承Thread类:Thread()
或Thread(String name)
多个线程分别完成自己的任务
实现Runnable接口:Thread(Runnable target)
或Thread(Runnable target, String name)
是多个线程共同完成一个任务
1.2.3:线程的启动
? 两种创建方式都是调用Thread对象的start()方法。当调用start()方法时,CPU会开启一条新线程,并在新线程上执行run()方法。
1.2.4:线程常用方法
? currentThread:静态方法,用来获取当前线程
? getName、setName:用来获取、设置当前线程的名字
? sleep:控制线程休眠,单位为毫秒
? setDaemon:将线程设置为守护线程。线程默认是非守护线程,守护线程不能单独执行。
? join:当前线程暂停,等待加入的线程运行结束,当前线程继续执行。
1.3:线程的同步:
? 同步代码块synchronized(锁对象){需要同步的代码...}形式将访问数据的代码锁住,在同步代码块中的内容同一时间内只能一个线程执行。
方法锁:如:public synchronized void testSyn(){}。同步非静态方法使用this作为锁,静态方法使用的是类对象本身
1.4:线程的生命周期:
1.新建状态(New):用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存
2.就绪状态(Runnable):当一个线程创建了以后,其他的线程调用了它的start()方法,该线程就进入了就绪状态。处于这个状态的 线程位于可运行池中,等待获得CPU的使用权
3.运行状态(Running): 处于这个状态的线程占用CPU,执行程序的代码
4.阻塞状态(Blocked): 当线程处于阻塞状态时,java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才有机会转到 运行状态。
阻塞状态分为三种情况:
1)、 位于对象等待池中的阻塞状态:当线程运行时,如果执行了某个对象的wait()方法,java虚拟机就回把线程放到这个对象的等待池中
2)、 位于对象锁中的阻塞状态,当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他的线程占用,JVM就会把这个线程放到这个对象的琐池中。
3)、 其它的阻塞状态:当前线程执行了sleep()方法,或者调用了其它线程的join()方法,或者发出了I/O请求时,就会进入这个状态中。
1.:5:多线程间的通信:
在同步代码中可以使用锁对象的wait()方法让当前线程等待
使用锁对象的notify()方法可以将正在等待的线程唤醒
? 如果多个线程都在等待,notify()唤醒随机1个
?notifyAll()方法可以唤醒所有在等待的线程
2.锁机制
3.内存的的可见性:
3.1.共享变量在线程间的可见性
共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。
可见性:一个线程对共享变量值的修改,能够及时地被其他线程看到。
Java内存模型(JMM:Java Memory Model():描述了java程序中各种变量的访问规则,以及在jvm中将变量存储到内存和从内存中读取变量这样的底层细节。
所有的变量都存储在主线程中
每个线程都有自己独立的工作内存,里面保存该线程使用的变量的副本(主内存中该变量的一份拷贝)
特点:1.线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写
2.不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量值的传递需要通过主内存来完成。
2.2.java语言层面支持的可见性实现方式(synchronized、volatile):
3.2.1:指令重排序:代码书写的顺序与实际执行的顺序不同,指令的重排序是编译器或处理器为了提高程序性能而做的优化
2.1:编译器优化的重排序(编译器优化)
2.2:指令级并行重排序(处理器优化)
2.3:内存系统的重排序(处理器优化)
3.2:as-if-serial语义:无论如何重排序,程序执行的结果应该与代码顺序执行的结果一致
1. jvm编译器,运行时和处理器都会保证java在单线程下遵循as-if-serial语义
2.
3.2.3:synchronized实现可见性
3.2.3.1:特性:原子性、可见性
3.2.3.2:线程解锁前,必须把共享变量的最新值刷新到主内存中,线程加锁时,将清空工作内存中共享变量的值
3.2.3.3:线程执行互斥代码过程:
1.获取互斥锁;
2.清空工作内存;
3.从主内存拷贝变量的最新副本到工作内存;
4.执行代码;
5把共享变量的最新值刷新到主内存中;
6释放互斥锁
3.2.4:volatile实现可见性
指令重排序
volatile使用注意事项
synchronized与volatile
标签:
原文地址:http://www.cnblogs.com/cjcblogs/p/4737903.html