资讯专栏INFORMATION COLUMN

静态的同步方法

jlanglang / 2471人阅读

摘要:静态方法的锁对象是本类的属性卖票案例出现了线程安全问题卖出了不存在的票和重复的票解决线程安全问题的二种方案使用同步方法使用步骤把访问了共享数据的代码抽取出来放到一个方法中在方法上添加修饰符格式定义方法的格式修饰符返回值类型方法名参数列表可能


静态方法的锁对象是本类的class属性
package com.itheima.demo08.Synchronized;
/*

卖票案例出现了线程安全问题
卖出了不存在的票和重复的票

解决线程安全问题的二种方案:使用同步方法
使用步骤:
    1.把访问了共享数据的代码抽取出来,放到一个方法中
    2.在方法上添加synchronized修饰符

格式:定义方法的格式
修饰符 synchronized 返回值类型 方法名(参数列表){
    可能会出现线程安全问题的代码(访问了共享数据的代码)
}

*/
public class RunnableImpl implements Runnable{

//定义一个多个线程共享的票源
private static int ticket = 100;


//设置线程任务:卖票
@Override
public void run() {
    System.out.println("this:"+this);//this:com.itheima.demo08.Synchronized.RunnableImpl@58ceff1
    //使用死循环,让卖票操作重复执行
    while(true){
        payTicketStatic();
    }
}

/*
    静态的同步方法
    锁对象是谁?
    不能是this
    this是创建对象之后产生的,静态方法优先于对象
    静态方法的锁对象是本类的class属性-->class文件对象(反射)
 */
public static /*synchronized*/ void payTicketStatic(){
    synchronized (RunnableImpl.class){
        //先判断票是否存在
        if(ticket>0){
            //提高安全问题出现的概率,让程序睡眠
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //票存在,卖票 ticket--
            System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");
            ticket--;
        }
    }

}

/*
    定义一个同步方法
    同步方法也会把方法内部的代码锁住
    只让一个线程执行
    同步方法的锁对象是谁?
    就是实现类对象 new RunnableImpl()
    也是就是this
 */
public /*synchronized*/ void payTicket(){
    synchronized (this){
        //先判断票是否存在
        if(ticket>0){
            //提高安全问题出现的概率,让程序睡眠
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //票存在,卖票 ticket--
            System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");
            ticket--;
        }
    }

}

}
package com.itheima.demo08.Synchronized;

/*

模拟卖票案例
创建3个线程,同时开启,对共享的票进行出售

*/
public class Demo01Ticket {

public static void main(String[] args) {
    //创建Runnable接口的实现类对象
    RunnableImpl run = new RunnableImpl();
    System.out.println("run:"+run);//run:com.itheima.demo08.Synchronized.RunnableImpl@58ceff1
    //创建Thread类对象,构造方法中传递Runnable接口的实现类对象
    Thread t0 = new Thread(run);
    Thread t1 = new Thread(run);
    Thread t2 = new Thread(run);
    //调用start方法开启多线程
    t0.start();
    t1.start();
    t2.start();
}

}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75600.html

相关文章

  • Java同步块简介

    摘要:同步块用来避免竞争。实际需要那种同步块视具体情况而定。在非同步的方法中的同步块的例子如下所示示例使用同步块构造器来标记一块代码是同步的。在同步构造器中用括号括起来的对象叫做监视器对象。他们的构造器引用同一个实例。 Java 同步块(synchronized block)用来标记方法或者代码块是同步的。Java同步块用来避免竞争。本文介绍以下内容: Java同步关键字(synchro...

    warnerwu 评论0 收藏0
  • @Java | Thread & synchronized - [ 线程同步锁 基本使用]

    摘要:线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他非同步方法对于静态同步方法,锁是针对这个类的,锁对象是该类的对象。 对实现了Runnable或者Callable接口类,可以通过多线程执行同一实例的run或call方法,那么对于同一实例中的局部变量(非方法变量)就会有多个线程进行更改或读取...

    Michael_Lin 评论0 收藏0
  • Java中synchronized关键字

    摘要:的关键字中的块使用关键字进行标记。由于每个类只有一个类对象存在于中,因此全局同时只有一个线程能够进入到同一个类的静态同步方法中。同步代码块使这种期望成为可能。注意同步代码块如何在括号中接受一个对象。相同的实例被传入两个不同的线程实例中。 Java的synchronized块标记一个方法或一个代码块为同步的。synchronized块能用于防止出现竞态条件。 Java的synchroni...

    lylwyy2016 评论0 收藏0
  • synchronized关键字使用详解

    摘要:基本使用同步代码块同步代码块延时秒,方便后面测试作用代码块时,方法中的,是指调用该方法的对象。那么这个时候使用关键字就需要注意了推荐使用同步代码块,同步的代码块中传入外部定义的一个变量。 简述 计算机单线程在执行任务时,是严格按照程序的代码逻辑,按照顺序执行的。因此单位时间内能执行的任务数量有限。为了能在相同的时间内能执行更多的任务,就必须采用多线程的方式来执行(注意:多线程模式无法减...

    Jeffrrey 评论0 收藏0
  • java 关键字总结

    摘要:关键字总结有个关键字,它们是接下来对其中常用的几个关键字进行概括。而通过关键字,并不能解决非原子操作的线程安全性。为了在一个特定对象的一个域上关闭,可以在这个域前加上关键字。是语言的关键字,用来表示一个域不是该对象串行化的一部分。 java 关键字总结 Java有50个关键字,它们是: abstract do implements private ...

    honmaple 评论0 收藏0
  • JAVA快速复习

    摘要:八种基本数据类型数组定义数组元素类型数组名元素类型元素个数和数组长度元素类型数组名元素类型元素元素元素元素内存的划分寄存器本地方法区方法区栈内存存储局部变量变量所属作用域一旦结束变量自动释放方法进栈局部变量属于方法所以方法要先进栈堆内存存储 八种基本数据类型 byte short int long boolean char float double JAVA数组 定义数组 元...

    cppowboy 评论0 收藏0

发表评论

0条评论

jlanglang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<