Java synchronize线程安全测试
线程的运行是与当前CPU的资源调度与时间片是有关系的,当一个线程中的执行到某一部分方法的时候轮到另外一个线程来执行相应的代码,所以还没有等到第一个线程执行完那么CPU有切换到另外一个线程来运行其相应的代码,所以这个时候假如操作公共的数据部分就会出现错误
为了解决这个问题,可以使用 synchronized 同步代码块来对公共部分进行同步操作
在用synchronize关键字修饰同步代码块时,运行代码发现不能交替卖票。 以下是初始代码
package com.itheima.Test; public class Test1a { public static void main(String[] args) { Ticket1a t1=new Ticket1a(); new Thread(t1,"A").start(); new Thread(t1,"B").start(); new Thread(t1,"C").start(); } } class Ticket1a implements Runnable{ int ticket=100; @Override public void run() { synchronized (Ticket1a.class) { while (true) { if (ticket<=0) { break; } try { Thread.sleep(20); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" sold "+(ticket--)); } } } }
运行结果:
A sold 100 A sold 99 A sold 98 A sold 97 A sold 96 A sold 95 A sold 94 A sold 93 A sold 92 A sold 91 . . . A sold 10 A sold 9 A sold 8 A sold 7 A sold 6 A sold 5 A sold 4 A sold 3 A sold 2 A sold 1
虽然解决了线程的安全问题,但是不能实现三个窗口交替卖票。后来仔细一看,是synchronize关键字修饰的代码块位置不对,相当于修饰了同步方法。
更改后:
@Override public void run() { while (true) { synchronized (Ticket1a.class) { if (ticket<=0) { break; } try { Thread.sleep(20); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" sold "+(ticket--)); } } }
这样就完成了线程安全的小测试。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
相关推荐
-
Java使用synchronized修饰方法来同步线程的实例演示
Java中可以使用关键字synchronized进行线程同步控制,实现关键资源顺序访问,避免由于多线程并发执行导致的数据不一致性等问题.synchronized的原理是对象监视器(锁),只有获取到监视器的线程才能继续执行,否则线程会等待获取监视器.Java中每个对象或者类都有一把锁与之相关联,对于对象来说,监视的是这个对象的实例变量,对于类来说,监视的是类变量(一个类本身是类Class的对象,所以与类关联的锁也是对象锁).synchronized关键字使用方式有两种:synchronized方法
-
Java多线程程序中synchronized修饰方法的使用实例
在Java 5以前,是用synchronized关键字来实现锁的功能. synchronized关键字可以作为方法的修饰符(同步方法),也可作用于函数内的语句(同步代码块). 掌握synchronized,关键是要掌握把那个东西作为锁.对于类的非静态方法(成员方法)而言,意味着要取得对象实例的锁:对于类的静态方法(类方法)而言,要取得类的Class对象的锁:对于同步代码块,要指定取得的是哪个对象的锁.同步非静态方法可以视为包含整个方法的synchronized(this) { - }代码块.
-
Java线程之线程同步synchronized和volatile详解
上篇通过一个简单的例子说明了线程安全与不安全,在例子中不安全的情况下输出的结果恰好是逐个递增的(其实是巧合,多运行几次,会产生不同的输出结果),为什么会产生这样的结果呢,因为建立的Count对象是线程共享的,一个线程改变了其成员变量num值,下一个线程正巧读到了修改后的num,所以会递增输出. 要说明线程同步问题首先要说明Java线程的两个特性,可见性和有序性.多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变量来实现.拿上篇博文中的例子来说明,在多个线程之间共享了Count类的
-
Java多线程编程中synchronized线程同步的教程
0.关于线程同步 (1)为什么需要同步多线程? 线程的同步是指让多个运行的线程在一起良好地协作,达到让多线程按要求合理地占用释放资源.我们采用Java中的同步代码块和同步方法达到这样的目的.比如这样的解决多线程无固定序执行的问题: public class TwoThreadTest { public static void main(String[] args) { Thread th1= new MyThread1(); Thread th2= new MyThread2(); th1.st
-
java synchronized加载加锁-线程可重入详解及实例代码
java synchronized加载加锁-线程可重入 实例代码: public class ReGetLock implements Runnable { @Override public void run() { get(); } public synchronized void get() { System.out.println(Thread.currentThread().getId()); set(); } public synchronized void set() { Syste
-
java多线程之线程,进程和Synchronized概念初解
一.进程与线程的概念 (1)在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单位都是进程. 在未配置 OS 的系统中,程序的执行方式是顺序执行,即必须在一个程序执行完后,才允许另一个程序执行:在多道程序环境下,则允许多个程序并发执行.程序的这两种执行方式间有着显著的不同.也正是程序并发执行时的这种特征,才导致了在操作系统中引入进程的概念. 自从在 20 世纪 60 年代人们提出了进程的概念后,在 OS 中一直都是以进程作为能拥有资源和独立运行的基本单位的.直到 20 世纪 8
-
Java多线程并发编程 Synchronized关键字
synchronized 关键字解析 同步锁依赖于对象,每个对象都有一个同步锁. 现有一成员变量 Test,当线程 A 调用 Test 的 synchronized 方法,线程 A 获得 Test 的同步锁,同时,线程 B 也去调用 Test 的 synchronized 方法,此时线程 B 无法获得 Test 的同步锁,必须等待线程 A 释放 Test 的同步锁才能获得从而执行对应方法的代码. 综上,正确使用 synchronized 关键字可确保原子性. synchronized 关键字的特
-
深入讲解java线程与synchronized关键字
我们将会从以下的几点理解java线程的一些概念: 线程的基本概念和优劣之处 创建一个线程的两种方式 线程的属性 线程的状态 synchronized可修饰的方法 synchronized的重要特性 一.线程的基本概念 在计算机中有进程和线程这么两个概念,进程中可以有多个线程,它们是从属关系,进程往往更像是资源的占有者,线程才是程序的执行者,多个线程之间共享着进程中的资源.一个cpu同时只能运行一个线程,每个线程都有一个时间片,时间片用完了就会被阻塞并让出CPU的控制权,交给下一个线程使用.这样在
-
Java synchronize线程安全测试
线程的运行是与当前CPU的资源调度与时间片是有关系的,当一个线程中的执行到某一部分方法的时候轮到另外一个线程来执行相应的代码,所以还没有等到第一个线程执行完那么CPU有切换到另外一个线程来运行其相应的代码,所以这个时候假如操作公共的数据部分就会出现错误 为了解决这个问题,可以使用 synchronized 同步代码块来对公共部分进行同步操作 在用synchronize关键字修饰同步代码块时,运行代码发现不能交替卖票. 以下是初始代码 package com.itheima.Test; publi
-
java 使用线程监控文件目录变化的实现方法
java 使用线程监控文件目录变化的实现方法 由于某种特殊的需求.弄了个使用线程监控文件目录变化的 代码基本如下.其中减去一些复杂的操作.只留下基本代码: package com.file; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; public
-
Java编程线程间通信与信号量代码示例
1.信号量Semaphore 先说说Semaphore,Semaphore可以控制某个资源可被同时访问的个数,通过acquire()获取一个许可,如果没有就等待,而release()释放一个许可.一般用于控制并发线程数,及线程间互斥.另外重入锁ReentrantLock也可以实现该功能,但实现上要复杂些. 功能就类似厕所有5个坑,假如有10个人要上厕所,那么同时只能有多少个人去上厕所呢?同时只能有5个人能够占用,当5个人中的任何一个人让开后,其中等待的另外5个人中又有一个人可以占用了.另外等待的
-
详解Java停止线程的四种方法
一.线程停止基础知识 interrupted(): 测试当前线程是否已经中断.该方法为静态方法,调用后会返回boolean值.不过调用之后会改变线程的状态,如果是中断状态调用的,调用之后会清除线程的中断状态. isInterrupted(): 测试线程是否已经中断.该方法由对象调用 interrupt(): 标记线程为中断状态,不过不会中断正在运行的线程. stop(): 暴力停止线程.已弃用. 二.停止线程方法1:异常法停止 线程调用interrupt()方法后,在线程的run方法中判断当前对
-
Java中线程Thread的三种方式和对比
介绍 多线程主要的作用就是充分利用cpu的资源.单线程处理,在文件的加载的过程中,处理器就会一直处于空闲,但也被加入到总执行时间之内,串行执行切分总时间,等于每切分一个时间*切分后字符串的个数,执行程序,估计等几分钟能处理完就不错了.而多线程处理,文件加载与差分过程中 一.Java实现多线程的三种方式 1.继承Thread 通过Thread继承,并重写run方法来实现多线程,案例如下: public class ThreadPattern extends Thread { @Override p
-
java中线程池最实用的创建与关闭指南
目录 前言 线程池创建 只需要执行shutdown就可以优雅关闭 执行shutdownNow关闭的测试 总结 前言 在日常的开发工作当中,线程池往往承载着一个应用中最重要的业务逻辑,因此我们有必要更多地去关注线程池的执行情况,包括异常的处理和分析等. 线程池创建 避免使用Executors创建线程池,主要是避免使用其中的默认实现,那么我们可以自己直接调用ThreadPoolExecutor的构造函数来自己创建线程池.在创建的同时,给BlockQueue指定容量就可以了. private stat
-
java 中断线程的几种方式 interrupt()详解
中断 中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其当前的操作.线程是死亡.还是等待新的任务或是继续运行至下一步,就取决于这个程序.虽然初次看来它可能显得简单,但是,你必须进行一些预警以实现期望的结果.你最好还是牢记以下的几点告诫. 首先,忘掉Thread.stop方法.虽然它确实停止了一个正在运行的线程,然而,这种方法是不安全也是不受提倡的,这意味着,在未来的JAVA版本中,它将不复存在. 如何安全的结束一个正在运行的线程 Thread类相关的方
-
java 并发线程个数的如何确定
目录 java 并发线程个数的确定 cpu密集型 io密集型 有锁的情况 java 线程池线程数量确定思路 多线程可以快速执行任务的原理 创建线程池需要的参数 确定线程数 java 并发线程个数的确定 本文从控制变量的角度来谈决定线程个数的依据.模型很简单,在实际的生产环境中,情况肯定比下文要复杂的多.要充分的进行测试,以使线程个数为优. java应用程序大概分为两种:cpu密集型和io密集型. cpu密集型 就是指线程大部分时间都在用cpu,一般来说,普通的操作都需要用到cpu,比如计算,读取
-
关于Java创建线程的2种方式以及对比
目录 1. 继承Thread类 2. 实现Runnable接口: 创建线程的两种方式对比: 线程的完整生命周期: 总结 Java中两种创建线程的方式: 1. 继承Thread类 重写run()方法 new一个线程对象 调用对象的start()启动线程 class Handler extends Thread{ public void run(){ //重写run()方法 } public static void main(String[] args){ Thread thread=new Han
-
Java守护线程和用户线程的区别
目录 守护线程定义 创建守护线程 将线程池设置为守护线程 守护线程 VS 用户线程 用户线程 守护线程 守护线程注意事项 总结 前言: 在 Java 语言中,线程分为两类:用户线程和守护线程,默认情况下我们创建的线程或线程池都是用户线程,所以用户线程也被称之为普通线程. 想要查看线程到底是用户线程还是守护线程,可以通过 Thread.isDaemon() 方法来判断,如果返回的结果是 true 则为守护线程,反之则为用户线程. 我们来测试一下默认情况下线程和线程池属于哪种线程类型?测试代码如下:
随机推荐
- Perl 批量添加Copyright版权信息
- IOS开发之UIScrollView实现图片轮播器的无限滚动
- JS实现选项卡实例详解
- ASP.NET中图片显示方法实例
- PHP sleep()函数, usleep()函数
- 基于python的七种经典排序算法(推荐)
- 实例详解Android快速开发工具类总结
- Apache+php+mysql在windows下的安装与配置图解(最新版)
- 会移动的文字(Marquee)
- 关闭显示器软件代码分享
- PHP的中问验证码
- ui组件之input多选下拉实现方法(带有搜索功能)
- jQuery筛选器children()案例详解(图文)
- 浅谈被jQuery抛弃的函数及替代函数
- 利用Bootstrap实现表格复选框checkbox全选
- Struts1和struts2的区别_动力节点Java学院整理
- Android中使用AsyncTask实现下载文件动态更新进度条功能
- asp.net 页面中添加普通视频的几种方式介绍
- Yii使用技巧大汇总
- AndroidManifest.xml <uses-feature>和<uses-permisstion>分析及比较