Java 线程安全问题
class Ticket extends Thread
{
private int num = 100;
public void run()
{
while(num > 0)
{
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "..." + num-- );
}
}
} public class MyDemo { public static void main(String[] args) {
// TODO Auto-generated method stub Runnable ticket = new Ticket(); Thread t1 = new Thread(ticket);
Thread t2 = new Thread(ticket);
Thread t3 = new Thread(ticket);
Thread t4 = new Thread(ticket); t1.start();
t2.start();
t3.start();
t4.start();
}
}
解决思路:
class Ticket implements Runnable
{
private int num = 100;
Object obj = new Object(); public void run()
{
// 如果将同步锁对象obj定义在此处,则会在每一个线程中都创建一个同步锁,
//即无法实现线程的同步。
while(true)
{
synchronized(obj) //同步代码块
{
if(num > 0)
{
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "..." + num--);
}
}
} } } public class MyDemo { public static void main(String[] args) {
// TODO Auto-generated method stub Runnable ticket = new Ticket(); Thread t1 = new Thread(ticket);
Thread t2 = new Thread(ticket);
Thread t3 = new Thread(ticket);
Thread t4 = new Thread(ticket);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Ticket extends Thread
{
private int num = 100;
Object obj = new Object(); public void run()
{ while(true)
{
synchronized(obj)
{
if(num > 0)
{
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "..." + num--);
}
}
} } } public class MyDemo { public static void main(String[] args) {
// TODO Auto-generated method stub Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
Ticket t3 = new Ticket();
Ticket t4 = new Ticket();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/*
同步函数的使用的锁是this;
同步函数和同步代码块的区别:
同步函数的锁是固定的this。
同步代码块的锁是任意的对象。
建议使用同步代码块。
*/
class Ticket implements Runnable
{
private int num = 100;
boolean flag = true;
public void run()
{
if(flag)
while(true)
{
synchronized(this)
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){}
System.out.println(Thread.currentThread().getName()+".....obj...."+num--);
}
}
}
else
while(true)
this.show();
} public synchronized void show()
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){} System.out.println(Thread.currentThread().getName()+".....function...."+num--);
}
}
} class SynFunctionLockDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket(); Thread t1 = new Thread(t);
Thread t2 = new Thread(t); t1.start();
try{Thread.sleep(10);}catch(InterruptedException e){}
t.flag = false;
t2.start();
}
}
/* synchronized作用于静态方法和非静态方法的区别:
* 非静态方法:
* 给对象加锁(可以理解为给这个对象的内存上锁,注意 只是这块内存,其他同类对象都会有各自的内存锁),这时候
* 在其他一个以上线程中执行该对象的这个同步方法(注意:是该对象)就会产生互斥
* 静态方法:
* 相当于在类上加锁(*.class 位于代码区,静态方法位于静态区域,这个类产生的对象公用这个静态方法,所以这块
* 内存,N个对象来竞争), 这时候,只要是这个类产生的对象,在调用这个静态方法时都会产生互斥
*/
class Ticket implements Runnable
{
private static int num = 100;
boolean flag = true;
public void run()
{ if(flag)
while(true)
{
synchronized(this.getClass()) // Ticket.class
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){}
System.out.println(Thread.currentThread().getName()+".....obj...."+num--);
}
}
}
else
while(true)
show();
} public static synchronized void show()
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){} System.out.println(Thread.currentThread().getName()+".....function...."+num--);
}
}
} class SynFunctionLockDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket(); Thread t1 = new Thread(t);
Thread t2 = new Thread(t); t1.start();
try{Thread.sleep(10);}catch(InterruptedException e){}
t.flag = false;
t2.start();
}
}
Java 线程安全问题的更多相关文章
- (转)java线程安全问题之静态变量、实例变量、局部变量
java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...
- java线程安全问题以及使用synchronized解决线程安全问题的几种方式
一.线程安全问题 1.产生原因 我们使用java多线程的时候,最让我们头疼的莫过于多线程引起的线程安全问题,那么线程安全问题到底是如何产生的呢?究其本质,是因为多条线程操作同一数据的过程中,破坏了数据 ...
- java线程安全问题之静态变量、实例变量、局部变量
java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...
- java线程安全问题原因及解决办法
1.为什么会出现线程安全问题 计算机系统资源分配的单位为进程,同一个进程中允许多个线程并发执行,并且多个线程会共享进程范围内的资源:例如内存地址.当多个线程并发访问同一个内存地址并且内存地址保存的值是 ...
- Java 线程安全问题的本质
原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录: 线程安全问题的本质 理解CPU JVM虚拟机类比于操作系统 重排序 汇总 一些解释 ...
- Java线程安全问题
线程安全问题是一个老生常谈的问题,那么多线程环境下究竟有那些问题呢?这么说吧,问题的形式多种多样的,归根结底的说是共享资源问题,无非可见性与有序性问题. 1. 可见性 可见性是对于内存中的共享资源来说 ...
- java线程安全问题原理性分析
1.什么是线程安全问题? 从某个线程开始访问到访问结束的整个过程,如果有一个访问对象被其他线程修改,那么对于当前线程而言就发生了线程安全问题:如果在整个访问过程中,无一对象被其他线程修改,就是线程安全 ...
- 关于 SimpleDateFormat 的非线程安全问题及其解决方案
一直以来都是直接用SimpleDateFormat开发的,没想着考虑线程安全的问题,特记录下来(摘抄的): 1.问题: 先来看一段可能引起错误的代码: package test.date; impor ...
- Java多线程--线程安全问题的相关研究
在刚刚学线程的时候我们经常会碰到这么一个问题:模拟火车站售票窗口售票.代码如下: package cn.blogs.com.isole; /* 模拟火车站售票窗口售票,假设有50张余票 */ publ ...
随机推荐
- day89 DjangoRsetFramework学习---restful规范,解析器组件,Postman等
DjangoRsetFramework学习---restful规范,解析器组件,Postman等 本节目录 一 预备知识 二 restful规范 三 DRF的APIView和解析 ...
- Asp.Net Core跨域配置
在没有设置跨域配置的时候,Ajax请求时会报以下错误 已拦截跨源请求:同源策略禁止读取位于 http://localhost:5000/Home/gettime 的远程资源.(原因:CORS 头缺少 ...
- 20155202 2016-2017-2《Java程序设计》课程总结
20155202 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 预备作业1:第一次写随笔,我眼中的师生关系--未来我的大学生活 预备作业2:第二次随笔-- ...
- WPF MVVM从入门到精通7:关闭窗口和打开新窗口
原文:WPF MVVM从入门到精通7:关闭窗口和打开新窗口 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 ...
- PostgreSQL的hstore初步学习
安装hstore: 进入源代码的 /contrib/hstore 目录,然后执行gmake 和 gmake install: [root@pg200 hstore]# gmake gcc -O2 -W ...
- [hdu6051]If the starlight never fade-[欧拉函数+原根]
Description 传送门 Solution orz大佬yxq..本题神仙 设g为P的原根. 设$x=g^{a}$,$y=g^{b}$. 由于$(g^{a}+g^{b})^{i}\equiv (g ...
- 【SQLSERVER】如何找出字符串中的数字
可以通过写自定义函数实现,以下提供两种思路来解决: 1.通过正则匹配,找到字符串中的数字,一个一个拼起来 /*方法一: 一个一个找出来*/ CREATE FUNCTION [dbo].[Fun_Get ...
- 【LG3236】[HNOI2014]画框
[LG3236][HNOI2014]画框 题面 洛谷 题解 和这题一模一样. 将最小生成树换成\(KM\)即可. 关于复杂度,因为决策点肯定在凸包上,且\(n\)凸包的期望点数为\(\sqrt {\l ...
- 【LG4587】[FJOI2016]神秘数
[LG4587][FJOI2016]神秘数 题面 洛谷 题解 首先我们想一想暴力怎么做 对于一段区间\([l,r]\) 我们先将它之间的数升序排序 从左往右扫, 设当前我们可以表示出的数为\([1,x ...
- [NOIp2018]货币系统 背包
LG传送门 完全背包板子题 显然就是判断有多少种面值的货币可以被其他面值的货币表示,完全背包搞一搞就好了. 考场代码(一看这两格缩进就知道是考场代码): #include<cstdio> ...