三种方法:

同步代码块:

synchronized(obj)

{

//obj表示同步监视器,是同一个同步对象

/**.....

TODO SOMETHING

*/

}

 

同步方法

格式:

在方法上加上synchronized修饰符即可。(一般不直接在run方法上加!)

synchronized 返回值类型 方法名(参数列表)

{

/**.....

TODO SOMETHING

*/

}

同步方法的同步监听器其实的是 this

静态方法的同步

同步方法

同步代码块

static不能和 this连用

静态方法的默认同步锁是当前方法所在类的.class对象

同步锁

jkd1.5后的另一种同步机制:

通过显示定义同步锁对象来实现同步,这种机制,同步锁应该使用Lock对象充当。

在实现线程安全控制中,通常使用ReentrantLock(可重入锁)。使用该对象可以显示地加锁和解锁。

具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

public class X {

private final ReentrantLock lock = new ReentrantLock();

//定义需要保证线程安全的方法

public void  m(){

//加锁

lock.lock();

try{

//... method body

}finally{

//在finally释放锁

lock.unlock();

}

}

}

修改后的例子:

//同步代码块

package july7;

class SellDemo implements Runnable{

private int num = 50;

@Override

public void run() {

for (int i = 0; i < 200; i++) {

synchronized (this) {

if(num > 0){

try {

//因为它不可以直接调用getName()方法,所以必须要获取当前线程。

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"卖出第"+num--+"张票!");

}

}

}

}

}

public class Demo3 {

public static void main(String[] args) {

SellDemo s = new SellDemo();

new Thread(s,"A").start();

new Thread(s,"B").start();

new Thread(s,"C").start();

}

}

//同步方法

package july7;

//同步方法

class FinalDemo1 implements Runnable {

private int num = 50;

@Override

public void run() {

for (int i = 0; i < 100; i++) {

gen();

}

}

public synchronized void gen() {

for (int i = 0; i < 100; i++) {

if (num > 0) {

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "卖出了第"

+ num-- + "张票!");

}

}

}

}

public class Demo6 {

public static void main(String[] args) {

FinalDemo1 f = new FinalDemo1();

new Thread(f, "A").start();

new Thread(f, "B").start();

new Thread(f, "C").start();

}

}

//线程同步锁

package july7;

import java.util.concurrent.locks.ReentrantLock;

//同步锁

class FinalDemo2 implements Runnable {

private int num = 50;

private final ReentrantLock lock = new ReentrantLock();

@Override

public void run() {

for (int i = 0; i < 100; i++) {

gen();

}

}

public void gen() {

lock.lock();

try{

//for (int i = 0; i < 100; i++) {

if (num > 0) {

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "卖出了第"

+ num-- + "张票!");

}

//}

}finally{

lock.unlock();

}

}

}

public class Demo7 {

public static void main(String[] args) {

FinalDemo2 f = new FinalDemo2();

new Thread(f, "A").start();

new Thread(f, "B").start();

new Thread(f, "C").start();

}

}

java 多线程安全问题的解决方法的更多相关文章

  1. python编程系列---多线程共享全局变量出现了安全问题的解决方法

    多线程共享全局变量出现了安全问题的解决方法 当多线程共享全局变量时,可能出现安全问题,解决机制----互斥锁:即在在一段与全局变量修改相关的代码中,假设一个时间片不足以完成全局变量的修改,就在这段代码 ...

  2. Java 多线程安全问题简单切入详细解析

    线程安全 假如Java程序中有多个线程在同时运行,而这些线程可能会同时运行一部分的代码.如果说该Java程序每次运行的结果和单线程的运行结果是一样的,并且其他的变量值也都是和预期的结果是一样的,那么就 ...

  3. Tomcat 优化 java.lang.OutOfMemoryError: Java heap space 的解决方法

    Tomcat 优化 java.lang.OutOfMemoryError: Java heap space 的解决方法 java.lang.OutOfMemoryError: Java heap sp ...

  4. java.lang.ClassNotFoundException的解决方法

    java.lang.ClassNotFoundException的解决方法   出现这个问题的原因可能很多,但是最终原因都是部署的项目文件中没有这个类包. 那么出错的点在哪呢?逐一排除! 1.首先在项 ...

  5. Tomcat部署java项目java.lang.OutOfMemoryError异常解决方法

    java.lang.OutOfMemoryError异常解决方法 Window系统环境下,在catalina.bat文件第一行添加以下内容 set JAVA_OPTS=-Xms512m -Xmx512 ...

  6. java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)

    上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // ...

  7. 对于jfinal中java.lang.Long cannot be cast to java.lang.Integer的解决方法

    @Jfinal 老大提供的解决方法 当数据库字段为 int 型(有符号int型),但是如果在 sql 中使用了某些函数,jdbc 会自动转型为 long,例如:select sum(money) fr ...

  8. android 工程里缺少 R.java 文件原因和解决方法

    作为新手,学习android 的时候难免要导入一些示例,目的为了更加了解android各种API用法,顺便也可以学习下别人代码的写法. 可是导入android源码后,基本都有错误,R.java也不会自 ...

  9. Java中线程出现Exception in thread "Thread-0" java.lang.IllegalMonitorStateException异常 解决方法

    代码 package thread; public class TestChongNeng { public static void main(String[] args) { Thread t1 = ...

随机推荐

  1. TypeScript类型检查机制

    类型推断 指不需要指定变量的类型,TS编译器可以根据某些规则自动推断出类型. 什么时候会有类型推断? 声明变量时没有指定类型 函数默认参数 函数返回值 ...... let a; // 这时自动推断为 ...

  2. 优化SQL之最佳索引

    SQL优化工具Tosska SQL Tuning Expert for Oracle,帮助SQL开发人员解决SQL性能问题. 本工具主要创始人Richard To, 资深ITPUB元老,从1996年开 ...

  3. Pod在多可用区worker节点上的高可用部署

    一. 需求分析 当前kubernetes集群中的worker节点可以支持添加多可用区中的ECS,这种部署方式的目的是可以让一个应用的多个pod(至少两个)能够分布在不同的可用区,起码不能分布在同一个可 ...

  4. JVM学习篇章(一)

    熟悉Java开发的同学,应该都知道jvm是什么,---它就是Java虚拟机,今天我们就学习一下:  内存分配原则:  常用的监控命令

  5. ServletConfig详解 (转载)

    ServletConfig详解  (转载)   容器初始化一个servlet时,会为这个servlet建一个唯一的ServletConfig.容器从DD读出Servlet初始化参数,并把这些参数交给S ...

  6. php中括号定义数组

    php5.3及之前的版本是不支持中括号定义数组的.5.4之后支持. 错误信息是,不识别“[”

  7. 获取表单所有字段 Post

    var params = $(".layui-form").serializeArray(); var values = {}; for (x in params) { value ...

  8. php 正则学习取反符号~

    php 正则学习取反符号~ ~(<a .*?>.*?</a>|<.*?>)~i 先看正则图形,有点偏差,但可以初步看出结果. 关于 ~ 是取反符号,看下面说明.

  9. 云原生应用 Kubernetes 监控与弹性实践

    前言 云原生应用的设计理念已经被越来越多的开发者接受与认可,而Kubernetes做为云原生的标准接口实现,已经成为了整个stack的中心,云服务的能力可以通过Cloud Provider.CRD C ...

  10. IP应用加速 – DCDN迈入全栈新篇章

    4月11日,第七届"亚太内容分发大会"暨CDN峰会国际论坛中,阿里云资深技术专家姚伟斌发布了DCDN子产品IP应用加速(IPA).IPA是基于阿里云CDN本身的资源优化,对传输层( ...