博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解决线程不安全的机制
阅读量:3960 次
发布时间:2019-05-24

本文共 3100 字,大约阅读时间需要 10 分钟。

1.synchronized关键字—监视器锁monitor lock

1)语法:作为方法的修饰符出现 作为代码块出现

public class SynchronizedDemo{
public synchronized void method(){
//具体代码 } }

说明:java中每个对象都有一个锁,叫监视锁(monitor lock)

作用:SynchronizedDemo o=new…();
o.method()
2)执行带synchronized修饰的普通方法时,首先需要lock引用指向的对象中的锁
如果可以锁,就正常执行代码
否则,需要等其他线程把锁unclock
如果一个线程lock到了锁,到方法执行结束时,就会unlock这把锁
3)锁在什么地方?
针对普通方法,所在调用该方法的引用指向的对象中(this)
synchronized代码表现
表现 锁的对象 什么时候加 什么时候释放
修饰普通方法 this 进入方法 退出方法
修饰静态方法 类 进入方法 退出方法
代码块 小括号引用指向的 进入代码块 退出代码块
Person.class就是类的对象(反射的知识)
代码示例1:锁的Synchronized对象

public class SynchronizedDemo {
public synchronized void method(){
} public static void main(String[] args) {
SynchronizedDemo demo=new SynchronizedDemo(); demo.method(); //计入方法会锁demo指向对象中的锁,出方法会释放demo指向对象中的锁 }}

代码示例2:锁的Synchronized类的对象

public class SynchronizedDemo {
public synchronized static void method(){
} public static void main(String[] args) {
method();//进入方法会锁SynchronizedDemo.class指向对象中的锁; //出方法会释放SynchronizedDemo.class中的锁 }}

代码示例3:明确锁的对象

public class SynchronizedDemo {
public void method(){
synchronized (this){
} } public static void main(String[] args) {
SynchronizedDemo demo=new SynchronizedDemo(); demo.method(); }}

代码示例:

class MyThread implements Runnable {
private int ticket = 1000; @Override public void run() {
for (int i = 0; i < 1000; i++) {
synchronized (this) {
if (this.ticket > 0) {
try {
Thread.sleep(20); } catch (InterruptedException e) {
} System.out.println(Thread.currentThread().getName() + ",还有" + this.ticket-- + "张票"); } } } }}public class TestDemo {
public static void main(String[] args) {
MyThread mt=new MyThread(); Thread t1=new Thread(mt,"黄牛A"); Thread t2=new Thread(mt,"黄牛B"); Thread t3=new Thread(mt,"黄牛C"); t1.start(); t2.start(); t3.start(); }}

2.volatile关键字

1.语法:修饰变量-变量修饰符

1)保证该变量的可见性问题
2)可以部分保证代码的重排序问题

Object object=new Object();

1.new 2.初始化 3.对象到引用的赋值
2可见性 可以保证重排序

3.关于对象中的等待集

1)wait方法:使线程停止运行

方法wait()的作用就是使当前执行代码的线程进行等待,wait(0方法是Object类的方法,该方法是用来将当前线程置入“与执行队列”中,并且在wait()所在的代码处执行,直接接到通知或被中断为止。
wait()方法只能在同步方法中或同步块中调用.如果调用wait()时,没有持有适当的锁,会抛出异常。
wait()方法执行后,当前线程释放锁,线程与其他线程竞争重新获取锁。
代码示例:观察:wait方法使用

public class Main2 {
public static void main(String[] args) throws InterruptedException {
Object object = new Object(); synchronized (object) {
System.out.println("等待中..."); object.wait(); System.out.println("等待已过..."); } System.out.println("main方法结束"); }}

2)notify()方法:使停止的线程继续运行

notify()也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁的其他线程,对其发出通知notify,并使它们重新获取该对的对象锁。如果有多个线程等待,则有线程规划器随机挑选出一个呈wait状态的线程
在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是推出同步代码块之后才会释放对象锁

3)notifyAll()方法

一次唤醒所有等待线程

转载地址:http://fylzi.baihongyu.com/

你可能感兴趣的文章
[移动] Mosquitto简要教程(安装/使用/测试)
查看>>
[HTML5] 关于HTML5(WebGL)的那点事
查看>>
自我反思
查看>>
初识网络编程
查看>>
很像动态规划的贪心
查看>>
东北赛选拔教训
查看>>
hash
查看>>
涨姿势了:求两个分子的最大公倍数
查看>>
快速幂
查看>>
vector.reserve and resize &&vector与map结合
查看>>
最短路
查看>>
最长公共子序列
查看>>
计算几何
查看>>
求解方程
查看>>
太弱了。。水题
查看>>
位运算(含应用)
查看>>
野指针与空指针
查看>>
图文混排效果
查看>>
urllib2.urlopen超时问题
查看>>
Choosing a Machine Learning Classifier
查看>>