1. 方式一:同步代码块
synchroized(同步监视器的对象){
需要被同步的代码
}
package threadtest;
//使用同步代码块实现Runable接口的线程
public class Ruanble { public static void main(String[] args) {
//创建实现类的对象
Num num=new Num();
//将此对象作为参数传递给Thread类的构造器,创建Thread类的对象
Thread thread1 =new Thread(num);
Thread thread2 =new Thread(num);
Thread thread3 =new Thread(num);
//调用start()启动创建的Thread对象 thread1.setName("线程一");
thread2.setName("线程二");
thread3.setName("线程三"); thread1.start();
thread2.start();
thread3.start();
}
}
//创建一个类实现Runable接口
class Num implements Runnable{
int ticket=100;
//定义同步监视器,多个线程共同使用唯一的同步监视器
Object obj=new Object();
//重写run方法
@Override
public void run() {
while (true) {
synchronized (obj) {
if (ticket>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"开始售票,票号为"+ ticket);
ticket--;
}else {
break;
}
} }
}
}
package threadtest;
//同步代码块实现继承Thread的线程
public class ThreadTest { public static void main(String[] args) {
//创建子类对象
EvenThread e1=new EvenThread();
EvenThread e2=new EvenThread();
EvenThread e3=new EvenThread();
//调用线程的start()启动
e1.setName("票口一");
e2.setName("票口二");
e3.setName("票口三"); e1.start();
e2.start();
e3.start();
} } //创建一个类继承与Thread类
class EvenThread extends Thread{
static int ticket=100;
//定义同步监视器,多个线程共同使用唯一的同步监视器
static Object obj=new Object();
//重写run方法
@Override
public void run() {
while (true) {
//synchronized (obj) {//方式一,确保同步监视器唯一
synchronized (EvenThread.class) {//EvenThread.class是唯一的
if (ticket>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"开始售票,票号为"+ ticket);
ticket--;
}else {
break;
}
} }
}
}

说明:共享数据------多个线程共同操作的数据

需要被同步的代码块,纪委操作共享的代码

同步监视器,俗称锁,任何一个类都可以充当同步监视器,但是,要求多个线程共用一个监视器

  1. 方式二:同步方法:如果操作共享数据的代码,完整的声明在相依的方法中,着我们可以考虑将此方法作为同步方法来写
  2. 非静态的同步方法的默认监视器是this,不能修改
  3. 静态的同步方法的监视器是当前类本身,不能修改
package threadtest;
//创建同步方法实现Runable的线程
public class Ruanble { public static void main(String[] args) {
//创建实现类的对象
Num num=new Num();
//将此对象作为参数传递给Thread类的构造器,创建Thread类的对象
Thread thread1 =new Thread(num);
Thread thread2 =new Thread(num);
Thread thread3 =new Thread(num);
//调用start()启动创建的Thread对象 thread1.setName("线程一");
thread2.setName("线程二");
thread3.setName("线程三"); thread1.start();
thread2.start();
thread3.start();
}
}
//创建一个类实现Runable接口
class Num implements Runnable{
int ticket=100;
//定义同步监视器,多个线程共同使用唯一的同步监视器
Object obj=new Object();
//重写run方法
@Override
public void run() {
while (true) {
push();
}
}
//同步方法
public synchronized void push() {//这里有默认的同步监视器this,是唯一的
if (ticket>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"开始售票,票号为"+ ticket);
ticket--;
}
}
}

//使用同步方法的来写继承Thread类的

package threadtest;

public class ThreadTest {

    public static void main(String[] args) {
//创建子类对象
EvenThread e1=new EvenThread();
EvenThread e2=new EvenThread();
EvenThread e3=new EvenThread();
//调用线程的start()启动
e1.setName("票口一");
e2.setName("票口二");
e3.setName("票口三"); e1.start();
e2.start();
e3.start();
} } //创建一个类继承与Thread类
class EvenThread extends Thread{
static int ticket=100;
//定义同步监视器,多个线程共同使用唯一的同步监视器
static Object obj=new Object();
//重写run方法
@Override
public void run() {
while (true) {
push();
}
}
//public synchronized void push() {//此时不加static,会在new EvenThred对象是,导致同步监视器不是唯一的,故加上static,让它先于类的创建而创建
public synchronized static void push(){
if (ticket>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"开始售票,票号为"+ ticket);
ticket--;
}
}
}

方式三使用lock锁来确保安全,见下篇博客:链接---->

https://www.cnblogs.com/ylblikestudyJava/p/12378013.html

java如何解决线程安全问题的更多相关文章

  1. Java之解决线程安全问题的方式三:Lock锁

    import java.util.concurrent.locks.ReentrantLock; /** * 解决线程安全问题的方式三:Lock锁 --- JDK5.0新增 * * 1. 面试题:sy ...

  2. java 22 - 12 多线程之解决线程安全问题的实现方式1

    从上一章知道了多线程存在着线程安全问题,那么,如何解决线程安全问题呢? 导致出现问题的原因: A:是否是多线程环境 B:是否有共享数据 C:是否有多条语句操作共享数据 上一章的程序,上面那3条都具备, ...

  3. java线程安全问题以及使用synchronized解决线程安全问题的几种方式

    一.线程安全问题 1.产生原因 我们使用java多线程的时候,最让我们头疼的莫过于多线程引起的线程安全问题,那么线程安全问题到底是如何产生的呢?究其本质,是因为多条线程操作同一数据的过程中,破坏了数据 ...

  4. 浅谈利用同步机制解决Java中的线程安全问题

    我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等 ...

  5. java并发之如何解决线程安全问题

    并发(concurrency)一个并不陌生的词,简单来说,就是cpu在同一时刻执行多个任务. 而Java并发则由多线程实现的. 在jvm的世界里,线程就像不相干的平行空间,串行在虚拟机中.(当然这是比 ...

  6. java 22 - 13 多线程之解决线程安全问题的实现方式2

    上一章说了,解决线程安全问题的实现方式1是使用同步代码块 同时也知道了,同步代码块的锁对象是任意对象:(Object obj ;  Demo d;)这些都行 那么,现在来说解决线程安全问题的实现方式2 ...

  7. Lock锁方式解决线程安全问题

    在JDK5.0之后新增加了一种更强大的线程同步机制---通过显示定义同步锁来实现线程同步解决线程安全问题.同步锁使用Lock对象充当. java.util.concurrent.locks.lock接 ...

  8. 逐步理解Java中的线程安全问题

    什么是Java的线程安全问题? 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读/写完,其他线程才可使用.不会出现数据不一致或者数据 ...

  9. java并发之线程安全问题

    并发(concurrency)一个并不陌生的词,简单来说,就是cpu在同一时刻执行多个任务. 而Java并发则由多线程实现的. 在jvm的世界里,线程就像不相干的平行空间,串行在虚拟机中.(当然这是比 ...

随机推荐

  1. tarjan求割点与割边

    tarjan求割点与割边 洛谷P3388 [模板]割点(割顶) 割点 解题思路: 求割点和割点数量模版,对于(u,v)如果low[v]>=dfn[u]那么u为割点,特判根结点,若根结点子树有超过 ...

  2. Linux 常用工具sysstat之iostat

    命令解释 用于输出CPU和磁盘I/O相关的统计信息:iostat依赖于sysstat软件包 命令格式 iostat [ 选项 ] [<时间间隔> [<次数>]] 常用选项 -c ...

  3. Nginx进阶

    常见的web架构 LAMP - Linux +Apache +MySQL + PHP LNMP - Linux +Nginx + Mysql + PHP RHEL开源  Linux系统  RHEL C ...

  4. 基于 Istio 与 Kubernetes 对应用进行灰度发布与 Tracing

    灰度发布,是指在黑与白之间,能够平滑过渡的一种发布方式.通俗来说,即让产品的迭代能够按照不同的灰度策略对新版本进行线上环境的测试,灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以对新版本进行测试 ...

  5. oracle11g和12c区别

    11g和12c 1.12c使用更为强大的sql执行与优化算法 2.oracle在12c完全使用云和可插拔数据库概念 3.oracle 12c的RAC使用flex(让rg直接化) 模式,让rg管理更加细 ...

  6. [Python]逻辑运算符 and or

    复习老男孩全栈二期视频的时候 圆号老师测试的用例两个集合and 和or操作的时候的问题 >>> a = set("what") >>> b = ...

  7. CCF_ 201512-4_送货

    一道拖了很久了题,用bool开的vis不会爆内存,dfs回溯的话会超时,于是有了一个很巧妙的dfs. #include<iostream> #include<cstring> ...

  8. Codeforces_714_B

    http://codeforces.com/problemset/problem/714/B 当不同大小整数有1.2个时,肯定成立,3个时,需要判断,大于等于4个,则肯定不成立. #include & ...

  9. 13.深度学习(词嵌入)与自然语言处理--HanLP实现

    笔记转载于GitHub项目:https://github.com/NLP-LOVE/Introduction-NLP 13. 深度学习与自然语言处理 13.1 传统方法的局限 前面已经讲过了隐马尔可夫 ...

  10. eclipse里新建work set,将项目分组放在不同文件夹

    想必大家的Eclipse里也会有这么多得工程...... 每次工作使用到的项目肯定不会太多...... 每次从这么大数量的工程当中找到自己要使用的, 必须大规模的滚动滚动条......有点不和谐了. ...