Java修炼——线程同步的俩种方法
当多线程去同时抢占CPU资源时,有多线程的安全问题。这时候就需要将线程同步。线程同步有俩个方法。
1.同步代码块(synchronize),同步代码块需要同步监视器,同步监视器是针对对象进行操作。什么对象时共享的,就可以给他加上同步监视器。
package com.bjsxt.ticker;
public class Ticket implements Runnable {
private int ticket=5;
@Override
public void run() {
for (int i = 0; i <100; i++) {//假设100个人再买票
synchronized (this) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"票");
}
}
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package com.bjsxt.ticker;
public class TestTicket01 {
public static void main(String[] args) {
Ticket t=new Ticket();
Thread t1=new Thread(t,"A窗口");
Thread t2=new Thread(t,"B窗口");
Thread t3=new Thread(t,"C窗口");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
打印输出结果:

2.第二种就是同步方法:
package com.bjsxt.ticker;
public class Ticket1 implements Runnable {
private int ticket=5;
@Override
public void run() {
for (int i = 0; i <100; i++) {//假设100个人再买票
this.saleTicket();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private synchronized void saleTicket() {//同步方法不需要指定同步监视器,同步监视器只能是当前对象this
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"票");
}
}
}
package com.bjsxt.ticker;
public class TestTicket01 {
public static void main(String[] args) {
Ticket1 t=new Ticket1();
Thread t1=new Thread(t,"A窗口");
Thread t2=new Thread(t,"B窗口");
Thread t3=new Thread(t,"C窗口");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
运行结果:

进行对比,我们将没有用线程同步的程序拿过来看看:
package com.bjsxt.ticker;
public class Ticket2 implements Runnable {
private int ticket=5;
@Override
public void run() {
for (int i = 0; i <100; i++) {//假设100个人再买票
if (ticket > 0) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"票");
}
}
}
}
package com.bjsxt.ticker;
public class TestTicket01 {
public static void main(String[] args) {
Ticket2 t=new Ticket2();
Thread t1=new Thread(t,"A窗口");
Thread t2=new Thread(t,"B窗口");
Thread t3=new Thread(t,"C窗口");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
运行结果:

可以看到,没有用同步方法,连0和-1都出来了,甚至还有俩个窗口卖同一张票的。这就是多线程没有用同步方法的线程安全。
Java修炼——线程同步的俩种方法的更多相关文章
- java中线程同步的几种方法
1.使用synchronized关键字 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态. 注: synchro ...
- JAVA之线程同步的三种方法
最近接触到一个图片加载的项目,其中有声明到的线程池等资源需要在系统中线程共享,所以就去研究了一下线程同步的知识,总结了三种常用的线程同步的方法,特来与大家分享一下.这三种方法分别是:synchroni ...
- Linux下线程同步的几种方法
Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1. 初始化锁 int pthrea ...
- 归纳一下:C#线程同步的几种方法
转自原文 归纳一下:C#线程同步的几种方法 我们在编程的时候,有时会使用多线程来解决问题,比如你的程序需要在后台处理一大堆数据,但还要使用户界面处于可操作状态:或者你的程序需要访问一些外部资源如数据库 ...
- Java中实现线程同步的三种方法
实现同步的三种方法 多线程共享数据时,会发生线程不安全的情况,多线程共享数据必须同步. 实现同步的三种方法: 使用同步代码块 使用同步方法 使用互斥锁ReetrantLock(更灵活的代码控制) 代码 ...
- java多线程二之线程同步的三种方法
java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Se ...
- Java多线程--实现同步的9种方法
我们通常说的保持同步,其实就是对共享资源的保护.在单线程模型中, 我们永远不用担心"多个线程试图同时使用同一个资源的问题", 但是有了并发, 就有可能发生多个线程竞争同一个共享资源 ...
- C#线程同步的几种方法
一.volatile关键字 volatile是最简单的一种同步方法,当然简单是要付出代价的.它只能在变量一级做同步,volatile的含义就是告诉处理器, 不要将我放入工作内存, 请直接在主存操作我. ...
- 【转】 Linux 线程同步的三种方法
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的 ...
随机推荐
- AngularJS: Error reports on $injector:modulerr
Angular JS最常见的问题是,程序启动失败,error为$injector:modulerr 错误是因为加载对应的Module失败,但很难找到需要修改的Module. 一个简单的小技巧是,不要使 ...
- windows7设置定时任务运行ThinkPHP框架程序
1. 设置Windows的任务计划 可以参考win7计划任务的设置方法 2. 新建Windows执行文件bat 新建cron.bat文件,内容如下: D: cd \wamp\www\tp32 D:\w ...
- nyoj 260-数数小木块 (打表)
260-数数小木块 内存限制:64MB 时间限制:3000ms 特判: No 通过数:17 提交数:24 难度:1 题目描述: 在墙角堆放着一堆完全相同的正方体小木块,如下图所示: 因为木块堆得实在是 ...
- .NET开发者的机遇与WebAssembly发展史(有彩蛋)
一.唠唠WebAssembly的发展历程 目前有很多支持WebAssembly的项目,但发展最快的是Blazor,这是一个构建单页面的.NET技术,目前已经从Preview版本升级到了beta版本,微 ...
- 2019-11-4:渗透测试,bypass学习,笔记
编码方式过wafurl编码,针对特殊情况可以两次URL编码十六进制编码,针对某些数据,如特殊字符,特殊字符串等unicode编码,使用两个字节编码一个字符,高位不足使用0填充单引号:%u0027.%u ...
- React躬行记(14)——测试框架
测试不仅可以发现和预防问题,还能降低风险.减少企业损失.在React中,涌现了多种测试框架,本节会对其中的Jest和Enzyme做详细的讲解. 一.Jest Jest是由Facebook开源的一个测试 ...
- 04_seaborn基本使用
1.seaborn设置整体风格 seaborn提供5中主题风格: darkgrid whitegrid dark white ticks 主要通过set()和set_style()两个函数对整体风格进 ...
- Linux安装python环境脚本
自动安装python环境的脚本 1.首先判断是不是root用户 2.判断是否安装 3.是否下载成功(网络可能有问题) 4.是否解压成功(文件下载可能缺少) 5.安装配置python环境 # codin ...
- linux任务计划cron、chkconfig工具、systemd管理服务、unit和target介绍
第8周第1次课(5月14日) 课程内容: 10.23 linux任务计划cron10.24 chkconfig工具10.25 systemd管理服务10.26 unit介绍10.27 target介绍 ...
- exportfs命令、NFS客户端问题、FTP介绍、使用vsftpd搭建ftp
6月22日任务 14.4 exportfs命令14.5 NFS客户端问题15.1 FTP介绍15.2/15.3 使用vsftpd搭建ftp 14.4 exportfs命令 当我们修改nfs的配置文件e ...