被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 虚拟机中的虚 ...
随机推荐
- Java生鲜电商平台-技术方案与文档下载
Java生鲜电商平台-技术方案与文档下载 说明:任何一个好的项目,都应该有好的文档与设计方案,包括需求文档,概要设计,详细设计,测试用例,验收报告等等,类似下面这个图: 有以下几个管理域: 1. 开发 ...
- MySql常用操作【基础且详细(●'◡'●)】
有那么挺长段时间没有敲代码了,今敲起来竟然有些sql都想不起来了
- Bootstrap-table表格插件的使用方法
前言 上次写了一个可拖动列表的插件,但除了这个特点没什么优点了,接下写的是我们常用的Bootstrap-table表格插件 正文 官网:https://bootstrap-table.com/ 有两个 ...
- 英语cartialgenous鹿茸cartialgenous单词
鹿茸cartialgenous是雄鹿未骨化密生茸毛的幼角,主要从梅花鹿和马鹿头上采收,前者叫花鹿茸.黄毛茸,后者叫青毛茸.雄鹿到了一定年纪头上就会长角,初发时嫩如春笋,其表面上有一层纤细茸毛的嫩角就是 ...
- pm2入门
简介 PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控.自动重启.负载均衡等,而且使用非常简单. 安装 全局安装,简直不能更简单. npm install -g ...
- 交换机与MPLS
在这一篇里面主要阐述交换机与MPLS的相似点.
- 201871010117-石欣钰《面向对象程序设计(java)》第十五周学习总结
项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址>http ...
- 201871020225-牟星源《面向对象程序设计(java)》第十五周学习总结
201871020225-牟星源<面向对象程序设计(java)>第十五周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- mysql的创建数据库表及添加数据
C:\Users\ceshi>mysql -u root -pEnter password: ******Welcome to the MySQL monitor. Commands end w ...
- 02-numpy-笔记-amin
>>> a = np.arange(4).reshape((2,2)) >>> a array([[0, 1], [2, 3]]) >>> np. ...