Java——多线程安全问题
/*
* 线程安全问题产生的原因:
* 1.多个线程操作共享的数据
* 2.操作共享数据的线程代码有多条
*
* 当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了云轩。就会导致线程安全问题的产生。
* 解决思路:
* 就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程不可以参与运算的。
* 必须要当前线程把这些代码都执行完成后,其他线程才可以参与运算。
*
* 在java中,用同步代码块就可以解决这个问题。
同步函数使用的锁是this
* 同步代码块的格式:
* synchronized(对象)
* {
*
需要被同步的 代码块;
* }
同步的好处:解决了线程的安全问题。
* 同步的弊端:相对降低了效率,因为同步外的线程都会判断同步锁。
同步函数使用的锁是this;
同步函数和同步代码块的区别:
同步函数的锁是固有的的this。
同步代码块的锁是任意的对象。
建议使用 同步代码块。
*/
class TicketTest implements Runnable
{
private int num = 100;
private Object obj = new Object();
@Override
public void run()
{
// TODO Auto-generated method stub
while(true)
{
synchronized(obj)
{
if(num>0)
{
System.out.println(Thread.currentThread().getName()+"------------"+num--);
}
else
break;
}
}
}
}
public class Ticket
{
public static void main(String[] args)
{
//创建一个线程任务对象
TicketTest t = new TicketTest();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
l
/*
* 建立一个线程任务:
* 目的是 向银行 每次存款 100, 存3次
同步函数使用的锁是this
*/
class Bkk implements Runnable
{
private Bank b = new Bank();
@Override
public void run()
{
// TODO Auto-generated method stub
for(int i=0; i<3; i++)
{
b.add(100);
}
}
}
class Bank
{
private int sum;
同步函数使用的锁是this
public synchronized void add(int num)//同步函数********************
{
sum += num;
System.out.println(sum);
}
}
public class LockTest
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
RenWu a = new RenWu(true);
RenWu b = new RenWu(false);
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t2.start();
}
}
//任务对象
class RenWu implements Runnable
{
private Boolean flag;//设定俩中情况
RenWu(Boolean flag)
{
this.flag = flag;
}
@Override
public void run()
{
// TODO Auto-generated method stub
if(flag)//让第一种情况去用第一把锁
{
synchronized (MyLock.Locka)
{
System.out.println(Thread.currentThread().getName()+".........."+ MyLock.Locka);
synchronized (MyLock.Lockb)//然后想用另外一把锁 这时发现 另外这把锁 有可能就被 另一个任务线程使用着
{
System.out.println(Thread.currentThread().getName()+".........."+ MyLock.Lockb);
}
}
}
else//让第二种情况去使用 第二把锁
{
synchronized (MyLock.Lockb)
{
System.out.println(Thread.currentThread().getName()+".........."+ MyLock.Lockb);
synchronized (MyLock.Locka)//然后想用另外一把锁 这时发现 另外这把锁 有可能就被 另一个任务线程使用着
{
System.out.println(Thread.currentThread().getName()+".........."+ MyLock.Locka);
}
}
}
}
}
//只有俩把锁 主要有其中一把锁 被锁上了 另外想用这吧锁的 这能等正在用的这把锁被打开后 才能使用
class MyLock
{
final static Object Locka = new Object();
final static Object Lockb = new Object();
}
l
版权声明:本文为博主原创文章,未经博主允许不得转载。
Java——多线程安全问题的更多相关文章
- Java 多线程安全问题简单切入详细解析
线程安全 假如Java程序中有多个线程在同时运行,而这些线程可能会同时运行一部分的代码.如果说该Java程序每次运行的结果和单线程的运行结果是一样的,并且其他的变量值也都是和预期的结果是一样的,那么就 ...
- java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)
上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // ...
- 【JAVA多线程安全问题解析】
一.问题的提出 以买票系统为例: class Ticket implements Runnable { public int sum=10; public void run() { while(tru ...
- java 多线程安全问题-同步代码块
/* 多线程的安全问题: while(true) { if(tick>0) { //线程0,1,2,3在余票为1时,都停滞在这里,之后分别获得CPU执行权,打印出0,-1,-2等错票 Syste ...
- java多线程安全问题-同步修饰符于函数
上一篇文章通过卖票使用同步代码块的方法解决安全问题本篇文章首先探讨如何找出这样的安全问题,并提出第二种方式(非静态函数synchronized修饰)解决安全问题 /* 需求: 银行有一个公共账号金库 ...
- Java多线程安全问题
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- java基础知识回顾之java Thread类学习(五)--java多线程安全问题(锁)同步的前提
这里举个例子讲解,同步synchronized在什么地方加,以及同步的前提: * 1.必须要有两个以上的线程,才需要同步. * 2.必须是多个线程使用同一个锁. * 3.必须保证同步中只能有一个线程在 ...
- java 多线程安全问题的解决方法
三种方法: 同步代码块: synchronized(obj) { //obj表示同步监视器,是同一个同步对象 /**..... TODO SOMETHING */ } 同步方法 格式: 在方法上加 ...
- java基础知识回顾之java Thread类学习(七)--java多线程安全问题(死锁)
死锁:是两个或者两个以上的线程被无限的阻塞,线程之间互相等待所需资源. 线程死锁产生的条件: 当两个线程相互调用Join()方法. 当两个线程使用嵌套的同步代码块的时候,一个线程占用了另一个线程的锁, ...
随机推荐
- 类似github的框架
github是程序员经常上的网站,但如果是在一家苦逼不能访问外网的公司,那不能把自己的代码托管在github上绝对是一件非常痛苦的事情.如果想要在公司内网也可以用github托管自己的代码,那就要自己 ...
- (转)SoftReference
本文介绍对象的强.软.弱和虚引用的概念.应用及其在UML中的表示. 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说, ...
- hdu1394
//Accepted 292 KB 46 ms //利用线段树求逆序数 //对于每个数看前面比他大的数有多少个,更新这个数的个数 #include <cstdio> #include &l ...
- 获得servletContext的路径的方法
request.getSession().getServletContext().getRealPath("")或 System.getProperty("webapp. ...
- C++数据结构之List--线性实现
List(表)类似于队列,不同于队列的是,list可以随机读取/修改/插入某一position,通过position这一位置信息就可以直接修改相应位置的元素.实现方式和队列的类似,多了个positio ...
- 无线安全渗透测试套件WiFi-Pumpkin新版本发布
WiFi-Pumpkin是一款无线安全检测工具,利用该工具可以伪造接入点完成中间人攻击,同时也支持一些其它的无线渗透功能.旨在提供更安全的无线网络服务,该工具可用来监听目标的流量数据,通过无线钓鱼的方 ...
- 利用烧鹅制作简单BadUSB,插谁谁怀孕
所用硬件设备为烧鹅,烧鹅是RadioWar基于Teensy++ 2.0 AT90USB1286芯片设计的USB Rubber Ducky类开发板. 使用veil编码meterpreter生成paylo ...
- Git 的安装和创建版本库 。
Git 的优点就不再多说了 .直接进入正题吧 . 安装Git 首先可以尝试输入 Git 看看有没有反映 . $ git The program 'git' is currently not insta ...
- BZOJ 1912 巡逻
重赋边权. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm& ...
- ERP通用存储过程封装(三)
一:解释 SQL Server提供了一种方法:可以将一些预先编译的SQL语句集中起来由SQL Server数据库服务器来完成以实现某个任务,这就是存储过程.存储过程常驻在SQL Server ...