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. epel-release的卸载重装

    1.yum remove epel-release 2.清空epel目录:rm -rf /var/cache/yum/x86_64/6/epel/ 3.安装,yum install  epel-rel ...

  2. laravel 服务容器的由来 代码展示

    <?php /** * 目的:代码的完善来说明从 基础类的调用到 工厂类的使用 再到容器的出现的原因 * (首先要明白工厂类和容器的关系 可以理解:容器就是工厂类的升级版(为了解决类的依赖)) ...

  3. 类加载之 <clinit>() 和 <init>()

    前序文章:深入理解Java类加载 <clinit>() 与 <init>() 区别 一.<clinit>() Java 类加载的初始化过程中,编译器按语句在源文件中 ...

  4. koa中间执行机制

    start 基于 koa 2.11 按以下流程分析: const Koa = require('koa'); const app = new Koa(); const one = (ctx, next ...

  5. std::wstring_convert处理UTF8

    扔掉MultiByteToWideChar 吧,使用std::wstring_convert和 std::codecvt_utf8 来处理UTF8与WChar之间的互转. VC和Clang都支持哦~ ...

  6. html作业记录

    <html> <head> <title>Hello World</title> </head> <body> <!-- ...

  7. C语言实现查询whois

    #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdl ...

  8. 第一次安装android studio遇到的问题

    安装android studio一点都不顺利,最后总是成功安装,但是忘了把问题记录下来,下一次肯定还肯能出现问题 忘了把问题记录下来了,好像是sync failed 第一次安装3.1.4遇到的问题,好 ...

  9. 基于LNMP架构部署NextCloud私有云盘

    一.NextCloud 概述 云盘这个词无论是做技术出身的朋友还是普通的网民.想必已经听的非常多了.在日常生活当中我们用的最多的云盘莫过于百度网盘了 在前几年百花齐放的网盘市场.到现如今只剩下了百度网 ...

  10. jmeter与jdk的安装

    1.第一步:下载jdk的安装包 下载链接: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151 ...