同步代码块

基本语句

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中解决多线程数据安全问题的更多相关文章

  1. java中的多线程 // 基础

    java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...

  2. Java中的多线程=你只要看这一篇就够了

    如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...

  3. Java中的多线程技术全面详解

    本文主要从整体上介绍Java中的多线程技术,对于一些重要的基础概念会进行相对详细的介绍,若有叙述不清晰或是不正确的地方,希望大家指出,谢谢大家:) 为什么使用多线程 并发与并行 我们知道,在单核机器上 ...

  4. Java 中传统多线程

    目录 Java 中传统多线程 线程初识 线程的概念 实现线程 线程的生命周期 常用API 线程同步 多线程共享数据的问题 线程同步及实现机制 线程间通讯 线程间通讯模型 线程中通讯的实现 @(目录) ...

  5. Java中使用多线程、curl及代理IP模拟post提交和get访问

    Java中使用多线程.curl及代理IP模拟post提交和get访问 菜鸟,多线程好玩就写着玩,大神可以路过指教,小弟在这受教,谢谢! 更多分享请关注微信公众号:lvxing1788 ~~~~~~ 分 ...

  6. Java中的 多线程编程

    Java 中的多线程编程 一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序 ...

  7. Android学习记录(5)—在java中学习多线程下载之断点续传②

    在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...

  8. Java中使用多线程、curl及代理IP模拟post提交和get訪问

    Java中使用多线程.curl及代理IP模拟post提交和get訪问 菜鸟,多线程好玩就写着玩.大神能够路过不吝赐教.小弟在这受教.谢谢! 很多其它分享请关注微信公众号:lvxing1788 ~~~~ ...

  9. java中解决组件重叠的问题(例如鼠标移动组件时)

    java中解决组件覆盖的问题!     有时候在移动组件的时候会出现两个组件覆盖的情况,但是你想让被覆盖的组件显示出来或者不被覆盖! 在设计GUI时已经可以定义组件的叠放次序了(按摆放组件的先后顺序) ...

随机推荐

  1. echarts 根据geojson 数据绘制区域图(精确到镇)

    步骤:1)先获取区域(县.镇)json数据 :2)使用echarts 绘制地图: 先上一波效果图(昆明市东川区) 一.获取区域json数据 1.下载工具"水经微图", 2.下载东川 ...

  2. MPP大规模并行处理架构详解

    面试官:说下你知道的MPP架构的计算引擎? 这个问题不少小伙伴在面试时都遇到过,因为对MPP这个概念了解较少,不少人都卡壳了,但是我们常用的大数据计算引擎有很多都是MPP架构的,像我们熟悉的Impal ...

  3. Tars | Win10下Docker部署TarsJava(SpringBoot)全过程及踩坑记录

    @ 目录 前言 1. 相关环境版本: 坑点一:VMware与Win10 Docker冲突 坑点二:20.版本TarsJava(SpringBoot)依赖文件缺失 2. Docker安装: 坑点三:Do ...

  4. Java:java获取Linux下的路径

    指定Linux的路径 //Linux系统路径 StringBuilder sb = new StringBuilder(File.separator); String Url = sb.append( ...

  5. vsftpd配置文件详解(转)

      vsftpd配置文件详解     1.默认配置: 1>允许匿名用户和本地用户登陆.      anonymous_enable=YES      local_enable=YES 2> ...

  6. Linux | 配置主机名称

    配置主机名称 为了便于在局域 网中查找某台特定的主机,或者对主机进行区分,除了要有 IP 地址外,还要为主机配置一个主机名,主机之间可以通过这个类似于域名的名称来相互访问. 在 Linux 系统中,主 ...

  7. IP地址与子网化分

    IP地址与子网掩码 一.IP地址的组成 二.IP地址的分类                            1)A.B.C三类地址的组成                            2 ...

  8. Java基础00-Debug11

    1. Debug 1.1 Debug概述 1.2 Debug操作流程 1.2.1 如何加断点 1.2.2 如何运行加了断点的程序 1.2.3 看哪里 1.2.4 点哪里 1.2.5 如何删除断点 多个 ...

  9. [刘阳Java]_JdbcTemplate用法_第11讲

    JdbcTemplate模板提供操作数据库的方法应用,下面我们来说一下它的用法(注意:建议大家结合Spring API文档学习效果更好,因为下面的代码只是"抱砖引玉") 1. 遵循 ...

  10. JAVA基础(代码)练习题61~90

    JAVA基础 61.设计一个方法打印数组{'a','r','g','s','e','r'}中下标为1和3的的元素 package Homework_90; /** * 设计一个方法打印数组{'a',' ...