被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否是线程安全
1 被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否线程安全?
/**
* (1)被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否线程安全?
* (2)线程安全问题都是由全局变量及静态变量引起的,若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;
* 若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能导致数据不一致
* (3)线程安全是指多个线程在执行同一段代码的时候采用加锁机制,线程不安全就是不提供加锁机制保护
* (4)在下面的例子中,如果method2方法都是通过method1调用的,那么程序执行没有问题,是线程安全的,但是method2也有可能同时被其他的线程调用,可能会对全局变或者静态变量进行修改,所以说method2线程不安全
*/
public class SynchronizedDemo1 { public static void main(String[] args) {
new Thread(() -> {
method1();
}).start(); new Thread(() -> {
method2();
}).start();
} private static synchronized void method1() {
method2();
} private static void method2() {
System.out.println(Thread.currentThread().getName() + "进入非Synchronized方法");
try {
TimeUnit.SECONDS.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "结束非Synchronized方法");
} }
2多个方法同步
/**
* synchronized可以实现方法的同步,a()和b()方法同步了,因为他们使用的是同一的对象
* 总结synchronized和lock的区别
* (1)synchronized关键字不能继承,如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,
* 而必须显式地在子类的这个方法中加上synchronized关键字才可以
* (2)synchronized是jvm内置锁,当获取锁的线程执行完同步代码或者发生异常,jvm会释放锁,两个线程争抢锁的过程中,a获取锁阻塞了,其他线程一直等待,不可中断,非公平锁,可重入,假如不可重入,
* 那么1个类的synchornized方法不能调用本类其他synchornized方法,也不能调用父类中的synchornized方法
* lock锁是显示锁,锁可中断,也可设置锁的等待时长,获取锁后必须手动释放锁,可以是公平锁也可以是非公平锁
*/
public class SynchronizedDemo2 {
public static void main(String[] args) {
People p = new People();
CountDownLatch latch = new CountDownLatch();
Thread a = new MyThread(p, ,latch);
Thread b = new MyThread(p, , latch);
a.start();
b.start();
latch.countDown(); }
} class People { public synchronized void a() {
for (int i = ; i < ; i++) {
System.out.print("A");
try {
Thread.sleep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } public synchronized void b() {
for (int i = ; i < ; i++) {
System.out.print("B");
try {
Thread.sleep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
} class MyThread extends Thread {
People p;
int c; CountDownLatch latch;
MyThread(People p, int c ,CountDownLatch latch) {
this.p = p;
this.c = c;
this.latch = latch;
} @Override
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (c == )
p.a();
else if (c == )
p.b();
}
}
3线程不安全的例子
/**
* 多个线程调用pass方法时,会对共享数据name和address发生修改,会造成数据不一致,线程不安全
*/
public class SynchronizedDemo3 { public static void main(String[] args) {
Gate gate = new Gate();
User bj = new User("Baobao", "Beijing", gate);
User sh = new User("ShangLao", "ShangHai", gate);
User gz = new User("GuangLao", "GuangZhou", gate); bj.start();
sh.start();
gz.start();
}
} class Gate {
private int counter = ;
private String name = "Nobody";
private String address = "Nowhere"; public synchronized void pass(String name, String address) {
this.counter++;
this.name = name;
this.address = address;
verify();
} private void verify() {
if (this.name.charAt() != this.address.charAt()) {
System.out.println("*******BROKEN********" + toString());
}
} public String toString() {
return "No." + counter + ":" + name + "," + address;
}
} class User extends Thread { private final String myName; private final String myAddress; private final Gate gate; public User(String myName, String myAddress, Gate gate) {
this.myName = myName;
this.myAddress = myAddress;
this.gate = gate;
} @Override
public void run() {
System.out.println(myName + " BEGIN");
while (true) {
this.gate.pass(myName, myAddress);
}
}
}
被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否是线程安全的更多相关文章
- 用juery的ajax方法调用aspx.cs页面中的webmethod方法示例
juery的ajax调用aspx.cs页面中的webmethod方法:首先在 aspx.cs文件里建一个公开的静态方法,然后加上WebMethod属性,具体实现如下,感兴趣的朋友可以参考下哈,希望对大 ...
- vue 父子组件传值以及方法调用,平行组件之间传值以及方法调用大全
vue项目经常需要组件间的传值以及方法调用,具体场景就不说了,都知道.基本上所有的传值都可以用vuex状态管理来实现,只要在组件内监听vuex就好. vue常用的传值方式以及方法有: 1. 父值传子( ...
- 用juery的ajax方法调用aspx.cs页面中的webmethod方法
首先在 aspx.cs文件里建一个公开的静态方法,然后加上WebMethod属性. 如: [WebMethod] public static string GetUserName() { //.... ...
- [Inside HotSpot] Java的方法调用
1. 方法调用模块入口 Java所有的方法调用都会经过JavaCalls模块.该模块又细分为call_virtual调用虚函数,call_static调用静态函数等.虚函数调用会根据对象类型进行方法决 ...
- JVM系列-方法调用的原理
JVM系列-方法调用的原理 最近重新看了一些JVM方面的笔记和资料,收获颇丰,尤其解决了长久以来心中关于JVM方法管理的一些疑问.下面介绍一下JVM中有关方法调用的知识. 目的 方法调用,目的是选择方 ...
- JVM方法调用过程
JVM方法调用过程 重载和重写 同一个类中,如果出现多个名称相同,并且参数类型相同的方法,将无法通过编译.因此,想要在同一个类中定义名字相同的方法,那么它们的参数类型必须不同.这种方法上的联系就是重载 ...
- 第164天:js方法调用的四种模式
js方法调用的四种模式 1.方法调用模式 function Persion() { var name1 = "itcast", age1 = 19, show1 = functio ...
- ActionMethod_DMI_动态方法调用
Action执行的时候并不一定要执行execute方法可以在配置文件中配置Action的时候用method=来指定执行那个方法,也可以在url地址中动态指定(动态方法调用DMI)(推荐) 动态方法调用 ...
- 04 JVM是如何执行方法调用的(下)
虚方法调用 Java 里所有非私有实例方法调用都会被编译成 invokevirtual 指令,而接口方法调用会被编译成 invokeinterface 指令.这两种指令,均属于 Java 虚拟机中的虚 ...
随机推荐
- C 数组、枚举类型enum
传递数组给函数 告诉编译器函数要接受一个指针 skip //函数声明,数组的长度无需声明,因为编译器不会对形式参数进行边界检查 void myFunction(int param[]) //或者 vo ...
- Python教程 | Requests的基本用法
下面我就给大家整理了Requests库的使用方法和细节. 什么是Requests Requests是Python语言编写,基于urllib3,采用Apache2 Licensed开源协议的HTTP库. ...
- Java生鲜电商平台-电商促销业务分析设计与系统架构
Java生鲜电商平台-电商促销业务分析设计与系统架构 说明:Java开源生鲜电商平台-电商促销业务分析设计与系统架构,列举的是常见的促销场景与源代码下载 左侧为享受促销的资格,常见为这三种: 首单 大 ...
- 高强度学习训练第二天总结:Opencv+Android+CameraView小demo
前言:网上已经有很多人将Opencv集成进Android项目中了.因此我只给大家看Gradle文件和项目目录. 1.gradle 三个gradle script // Top-level build ...
- BBR加速 Centos
BBR是什么 BBR 是 Google 提出的一种新型拥塞控制算法,可以使 Linux 服务器显著地提高吞吐量和减少 TCP 连接的延迟. BBR项目地址 https://github.com/goo ...
- 7 CentOS 7网卡配置
首先重中之重:修改前一定要进行系统备份,如果是虚拟机进行快照 查看虚拟机的网卡配置 注意桥接模式和NAT模式 桥接模式:网络层面,虚拟机和PC处于同级地位,虚拟机直接和路由器相连 NA ...
- Jenkins + Pipeline + Git + Maven (十)
一.准备环境介绍 192.168.5.71 # gitlab 仓库IP 192.168.5.72 # 开发环境,用于提交代码等 192.168.5.73 # tomcat 部署solo服务站点 192 ...
- 简单的深度神经网络实现——使用PyTorch
使用的数据集是MNIST,预期可以达到98%左右的准确率. 该神经网络由一个输入层,一个全连接层结构的隐含层和一个输出层构建. 1.配置库和配置参数 import torch import torch ...
- kali下ll命令无法使用
重装了系统之后,使用ll命令竟然发现报错了. bash: ll:未找到命令 果断解决一波: vim ~/.bashrc 将alias ll=’ls -l‘前面的注释符号#删掉 运行 问题完 ...
- JavaEE开发环境配置
JavaEE开发环境配置 Tomcat的下载和安装 1.登录Tomcat 站点,下载Tomcat最新版本http://tomcat.apache.org/Windows平台下载ZIP包,LInux平台 ...