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. Linux 安装Jenkins

    1.安装jdk1.8 下载地址:https://github.com/frekele/oracle-java/releases 下载 root@123:~/my_java# wget https:// ...

  2. mybatis 执行流程以及初用错误总结

    mappper 配置文件  头文件: 1.   <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" &q ...

  3. flask插件全家桶集成学习---持续更新ing

    不得不说flask的设计要比django要小巧精妙的多了,没有那么臃肿,只保留核心功能,其他的都需要自己引入,即各种各样的插件来满足我们的需求,我这里记录一下自己学习项目中用的插件使用方法和一些技巧总 ...

  4. Kubernetes学习(一)

    一 安装 三台机器搭建K8S集群,一台master两台woker Docker 18.09.0---kubeadm-1.14.0-0 kubelet-1.14.0-0 kubectl-1.14.0-0 ...

  5. IDEA | 识别不出自建webapp文件夹

    背景: 今天自建了一个webapp文件夹,发现idea识别不出来是web应用的资源文件夹 解决方案 打开project structure配置,如下图

  6. SASS用法入门

    本文参考了 阮一峰 老师对 SASS 用法的讲解. 学过 CSS 的人都知道,它不是一种编程语言,在日常的开发中,经常要写大量的 css 代码,有很多的重复代码,效率很低.Sass 是一个 CSS 的 ...

  7. c++中的动态内存分配

    使用new和delete动态的分配和释放内存 使用new来分配新的内存块,通常情况下,如果成功,new将返回一个指针,指向分配的内存,否则将引发异常,使用new时,需要指定要为那种数据类型分配内存: ...

  8. 8、OSPF

    OSPF ---最短路径优先 用于在单一自治系统(Autonomous System-AS)内决策路由 自制系统(AS)AS: 执行统一路由策略的一组网络设备的组合可适应大规模的网络: ·    路由 ...

  9. Spring基于注解配置AOP

    D:\Java\IdeaProjects\JavaProj\SpringHelloWorld\src\aop.xml <?xml version="1.0" encoding ...

  10. gcc 相关总结 动态链接库

    #include < >与#include " " #include < >:直接到系统指定的目录中去找头文件. #include " " ...