Java中解决多线程数据安全问题
同步代码块
基本语句
synchronized (任意对象) {
操作共享代码
}
代码示例
public class SellTicket implements Runnable {
private int tickets = 100;
private Object object = new Object();
@Override
public void run() {
while (true) {
synchronized (object) {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
}
}
}
public static void main(String[] args) {
SellTicket sellTicket = new SellTicket();
Thread thread1 = new Thread(sellTicket, "窗口1");
Thread thread2 = new Thread(sellTicket, "窗口2");
Thread thread3 = new Thread(sellTicket, "窗口3");
thread1.start();
thread2.start();
thread3.start();
}
}
优缺点:
- 解决了多线程的数据安全问题
- 多线程时,每个线程都会判断同步上的锁,耗费资源,降低了程序的运行效率
同步方法
同步方法:将synchronized关键字加到方法上
- 格式: 修饰符 synchronized 返回值类型 方法名(){ }
- 同步方法的锁对象是this
同步静态方法,就是把synchronized关键字加到静态方法上
- 格式: 修饰符 static synchronized 返回值类型 方法名(){ }
- 同步静态方法的锁对象是 类名.class
代码示例
public class SellTicket implements Runnable {
// private int tickets = 100;
private static int tickets = 100;
private Object object = new Object();
private int x = 0;
@Override
public void run() {
while (true) {
if (x % 2 == 0) {
// synchronized (object) {
// synchronized (this) {
synchronized (SellTicket.class) {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
}
} else {
// synchronized (object) {
// if (tickets > 0) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
// tickets--;
// }
// }
sellTicket();
}
x++;
}
}
// private void sellTicket(){
// synchronized (object) {
// if (tickets > 0) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
// tickets--;
// }
// }
// }
// private synchronized void sellTicket(){
// if (tickets > 0) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
// tickets--;
// }
private static synchronized void sellTicket(){
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
}
public static void main(String[] args) {
SellTicket sellTicket = new SellTicket();
Thread thread1 = new Thread(sellTicket, "窗口1");
Thread thread2 = new Thread(sellTicket, "窗口2");
Thread thread3 = new Thread(sellTicket, "窗口3");
thread1.start();
thread2.start();
thread3.start();
}
}
lock锁
lock实现提供比使用synchronized方法和语句可获得更广泛的操作
- void lock()获得锁
- void unlock()释放
lock是接口不能直接实例化,采用实现类实例化ReentrantLock
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SellTicket implements Runnable {
private int tickets = 100;
private Object object = new Object();
private Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
try {
lock.lock();
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
SellTicket sellTicket = new SellTicket();
Thread thread1 = new Thread(sellTicket, "窗口1");
Thread thread2 = new Thread(sellTicket, "窗口2");
Thread thread3 = new Thread(sellTicket, "窗口3");
thread1.start();
thread2.start();
thread3.start();
}
}
Java中解决多线程数据安全问题的更多相关文章
- java中的多线程 // 基础
java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...
- Java中的多线程=你只要看这一篇就够了
如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...
- Java中的多线程技术全面详解
本文主要从整体上介绍Java中的多线程技术,对于一些重要的基础概念会进行相对详细的介绍,若有叙述不清晰或是不正确的地方,希望大家指出,谢谢大家:) 为什么使用多线程 并发与并行 我们知道,在单核机器上 ...
- Java 中传统多线程
目录 Java 中传统多线程 线程初识 线程的概念 实现线程 线程的生命周期 常用API 线程同步 多线程共享数据的问题 线程同步及实现机制 线程间通讯 线程间通讯模型 线程中通讯的实现 @(目录) ...
- Java中使用多线程、curl及代理IP模拟post提交和get访问
Java中使用多线程.curl及代理IP模拟post提交和get访问 菜鸟,多线程好玩就写着玩,大神可以路过指教,小弟在这受教,谢谢! 更多分享请关注微信公众号:lvxing1788 ~~~~~~ 分 ...
- Java中的 多线程编程
Java 中的多线程编程 一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序 ...
- Android学习记录(5)—在java中学习多线程下载之断点续传②
在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...
- Java中使用多线程、curl及代理IP模拟post提交和get訪问
Java中使用多线程.curl及代理IP模拟post提交和get訪问 菜鸟,多线程好玩就写着玩.大神能够路过不吝赐教.小弟在这受教.谢谢! 很多其它分享请关注微信公众号:lvxing1788 ~~~~ ...
- java中解决组件重叠的问题(例如鼠标移动组件时)
java中解决组件覆盖的问题! 有时候在移动组件的时候会出现两个组件覆盖的情况,但是你想让被覆盖的组件显示出来或者不被覆盖! 在设计GUI时已经可以定义组件的叠放次序了(按摆放组件的先后顺序) ...
随机推荐
- Burning Bridges 求tarjan求割边
Burning Bridges 给出含有n个顶点和m条边的连通无向图,求出所有割边的序号. 1 #include <cstdio> 2 #include <cstring> 3 ...
- LAMP——实现phpMyadmin、wordpress及Discuz应用部署
一.环境准备 操作系统:Centos8.3.2011 软件:Apache2.4.37.Mysql8.0.21.PHP7.2.24 二.安装过程 1.安装phpmyadmin 1.1.安装软件包并启动服 ...
- acwing 4 多重背包问题 I
多重背包 有 n种物品 一共有 m大小的背包,每种物品的价值 大小 个数 为 s[i],v[i],num[i]; #include<bits/stdc++.h>//cmhao #defin ...
- 24 shell 管道命令与过滤器
1.管道命令的用法 2.使用管道命令的好处: 3.重定向和管道的区别 4.Linux管道实例 5.管道与重定向 1)管道与输入重定向 2)管道与输出重定向 6.过滤器 7.过滤器举栗 1.管道命令的用 ...
- python使用笔记26--多线程、多进程
1.概念 线程.进程 进程是资源的集合,也就是一个程序 线程是一个程序运行的最小单位 线程是在进程里面的 默认,一个进程就只有一个线程 一个电脑有几核CPU就只能同时运行几个任务,比如4核CPU只能同 ...
- 「 题解」NOIP2021模拟赛(2021-07-19)
小兔的话 欢迎大家在评论区留言哦~ D - 矩阵 简单题意 一个 \(i * i\) 的 \(01\) 矩阵,若满足 每一行 和 每一列 都满足 恰好 有 \(2\) 个位置是 \(1\) 时,称为 ...
- C语言:按相反顺序输出字符
#include <stdio.h> void pailie(int n) { char next; if (n<=1) { next=getchar(); putchar(next ...
- PYTHON 使用re.findall如果没有引用
python使用re.findall时必须提前import re否则不提示错误,只是找不到结果 import re ab=re.findall('cmp=com.(.*?)/',aa)
- 数据库里的回车字符导致取过来的json字符串不规范的问题
转发:https://bbs.csdn.net/topics/380192638 你可以报保存数据库之前,进行 替换 str = str.Replace("\r\n"," ...
- YsoSerial 工具常用Payload分析之URLDNS
本文假设你对Java基本数据结构.Java反序列化.高级特性(反射.动态代理)等有一定的了解. 背景 YsoSerial是一款反序列化利用的便捷工具,可以很方便的生成基于多种环境的反序列化EXP.ja ...