线程知识点

一、volatile关键字

volatile关键字的目的是告诉虚拟机:
1.每次访问变量时,总是获取主内存的最新值;
2.每次修改变量后,立刻回写到主内存。

volatile关键字解决的是可见性问题:当一个线程修改了某个共享变量的值,其他线程能够立刻看到修改后的值。
volatile关键字解决了共享变量在线程间的可见性问题。

二、守护线程

Java程序入口就是由JVM启动main线程,main线程又可以启动其他线程。当所有线程都运行结束时,JVM退出,进程结束。
守护线程是指为其他线程服务的线程。在JVM中,所有非守护线程都执行完毕后,无论有没有守护线程,虚拟机都会自动退出。
Thread t = new MyThread();
t.setDaemon(true);
t.start();
在守护线程中,编写代码要注意:守护线程不能持有任何需要关闭的资源,例如打开文件等,因为虚拟机退出时,守护线程没有任何机会来关闭文件,这会导致数据丢失。

三、同步
多线程同时读写共享变量时,会造成逻辑错误,因此需要通过synchronized同步;
同步的本质就是给指定对象加锁,加锁后才能继续执行后续代码;
注意加锁对象必须是同一个实例;
对JVM定义的单个原子操作不需要同步。

四、synchronized的使用

* 我们来概括一下如何使用synchronized:
* 找出修改共享变量的线程代码块;
* 选择一个共享实例作为锁;
* 使用synchronized(lockObject) { ... }

五、可重入锁

* Java的线程锁是可重入的锁。
* 对同一个线程,能否在获取到锁以后继续获取同一个锁?
* 答案是肯定的。JVM允许同一个线程重复获取同一个锁,这种能被同一个线程反复获取的锁,就叫做可重入锁。
* 由于Java的线程锁是可重入锁,所以,获取锁的时候,不但要判断是否是第一次获取,还要记录这是第几次获取。
* 每获取一次锁,记录+1,每退出synchronized块,记录-1,减到0的时候,才会真正释放锁。
* Java的synchronized锁是可重入锁;
* 死锁产生的条件是多线程各自持有不同的锁,并互相试图获取对方已持有的锁,导致无限等待;
* 避免死锁的方法是多线程获取锁的顺序要一致。

六、wait方法和notify方法的使用

* wait()方法的执行机制非常复杂。
* 首先,它不是一个普通的Java方法,而是定义在Object类的一个native方法,也就是由JVM的C代码实现的。
* 其次wait()方法调用时,会释放线程获得的锁,wait()方法返回后,线程又会重新试图获得锁。
* 因此,只能在锁对象上调用wait()方法。

* 必须在已获得的所对象上调用notify()或者notifyAll()方法。

* 已唤醒的线程还需要重新获得锁后才能继续执行。

 

多线程协调运行的原则就是:当条件不满足时,线程进入等待状态;当条件满足时,线程被唤醒,继续执行任务。

你可能感兴趣的:(线程知识点)