首页 > 其他分享 >synchronized

synchronized

时间:2024-10-27 14:23:34浏览次数:2  
标签:stats synchronized void cash new public

静态方法跟普通的synchronized方法有所区别,需要特别注意的是,虽然静态的同步方法仅允许同时只有一个线程参与访问,但与此同时其他线程依然可以访问另一个由synchronized修饰的非静态方法。在这里,虽然两个线程都是访问同一个对象实例上的方法(其中一个是静态方法,而另一个不是),但是这两个方法却绑定了不同的对象。因此当通过这两个方法修改同一份共享数据时,可能会带来数据一致性的错误。造成该错误的原因是,当程序由synchronized修饰的静态方法调用时,此时方法所关联的对象是类对象而并非该类的实例对象

金额类

package parkingsystem;

public class ParkingCash {
    private static final int cost = 2;

    private long cash;

    public ParkingCash() {
        cash = 0;
    }

    public synchronized void vehiclePay() {
        cash += cost;
    }

    public void close() {
        System.out.printf("Closing accounting");
        long totalAmmount;
        synchronized (this) {
            totalAmmount = cash;
            cash = 0;
        }
        System.out.printf("The total amount is : %d",
                totalAmmount);
    }
}

状态类

package parkingsystem;

public class ParkingStats {
    private final Object controlCars, controlMotorcycles;
    private long numberCars;
    private long numberMotorcycles;
    private ParkingCash cash;

    public ParkingStats(ParkingCash cash) {
        numberCars = 0;
        numberMotorcycles = 0;
        controlCars = new Object();
        controlMotorcycles = new Object();
        this.cash = cash;
    }

    public void carComeIn() {
        synchronized (controlCars) {
            numberCars++;
        }
    }

    public void carGoOut() {
        synchronized (controlCars) {
            numberCars--;
        }
        cash.vehiclePay();
    }

    public void motoComeIn() {
        synchronized (controlMotorcycles) {
            numberMotorcycles++;
        }
    }

    public void motoGoOut() {
        synchronized (controlMotorcycles) {
            numberMotorcycles--;
        }
        cash.vehiclePay();
    }

    public long getNumberCars() {
        return numberCars;
    }

    public long getNumberMotorcycles() {
        return numberMotorcycles;
    }
}

模拟停车行为类

package parkingsystem;

import java.util.concurrent.TimeUnit;

public class Sensor implements Runnable {
    private ParkingStats stats;

    public Sensor(ParkingStats stats) {
        this.stats = stats;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            stats.carComeIn();
            stats.carComeIn();
            try {
                TimeUnit.MILLISECONDS.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            stats.motoComeIn();
            try {
                TimeUnit.MILLISECONDS.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            stats.motoGoOut();
            stats.carGoOut();
            stats.carGoOut();
        }
    }
}

测试类Main

package parkingsystem;

public class Main {
    public static void main(String[] args) {
        ParkingCash cash = new ParkingCash();
        ParkingStats stats = new ParkingStats(cash);

        System.out.printf("Parking Simulator\n");
        int numberSensors = 2 * Runtime.getRuntime().availableProcessors();
        Thread threads[] = new Thread[numberSensors];
        for (int i = 0; i < numberSensors; i++) {
            Sensor sensor = new Sensor(stats);
            Thread thread = new Thread(sensor);
            thread.start();
            threads[i] = thread;
        }

        for (int i = 0; i < numberSensors; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.printf("Number of cars: %d\n",
                stats.getNumberCars());
        System.out.printf("Number of motorcycles: %d\n",
                stats.getNumberMotorcycles());
        cash.close();
    }
}

标签:stats,synchronized,void,cash,new,public
From: https://www.cnblogs.com/506740640zl/p/18508292

相关文章

  • 线程安全、synchronized和volatile关键字
    一、什么是线程安全?多线程下并发同时对共享数据进行读写,会造成数据混乱=线程不安全当多线程并发访问临界资源时,如果破坏其原子性、可见性、有序性,可能会造成数据不一致。临界资源:共享资源(同一对象)同时读写,一次仅允许一个线程使用,才可保证其正确性。1.1synchronizedsync......
  • 并发编程中锁Synchronized和ReentrantLock,CAS,AQS理解
    SynchronizedJAVA关键字,独占式的悲观锁,可重入锁。主要解决多个线程之间的访问资源的同步性,可以保证被他修饰的方法或者代码块在任意时刻只能有一个线程执行早期是重量级锁,JAVA6后引入大量优化,自旋锁,适应性自旋锁,偏向锁,轻量级锁,锁消除,锁粗化减少锁的开销使用方式修饰......
  • 【JavaEE】【多线程】synchronized和死锁
    目录一、synchronized详解1.1互斥1.2可重入二、死锁2.1死锁成因2.2避免死锁一、synchronized详解1.1互斥synchronized会起到互斥效果,某个线程执行到某个对象的synchronized中时,其他线程如果也执行到同一个对象synchronized就会阻塞等待.语法:sy......
  • Synchronized锁和Reentrantlock的区别和联系以及锁升级
    二者的底层实现:Synchronized就是基于monitor对象主要的为Owner获得这个锁资源的线程唯一标识符(线程ID)Count线程获得几次锁(可重入锁的实现)ContentionList等待队列(线程加锁失败的情况下)Reentrantlock是基于AQS这个就是表示是哪一个线程获得这个锁资源    ......
  • JAVA基础: synchronized 和 lock的区别、synchronized锁机制与升级
    1synchronized和lock的区别synchronized是一个关键字,lock是一个接口,实际使用的是实现类synchronized通过触发的是系统级别的锁机制,lock是API级别的锁机制synchronized自动获得锁,自动释放锁。lock需要通过方法获得锁并释放锁synchronized可以修饰代码段和方法,lock......
  • 说一下synchronized的锁的升级和降级
    在Java中,synchronized关键字使用的锁有状态的升级和降级过程,主要涉及偏向锁、轻量级锁和重量级锁。一、偏向锁(BiasedLocking)引入目的:在没有竞争的情况下,减少锁获取的开销。很多情况下,一个对象在被一个线程使用时,不存在多线程竞争,此时使用偏向锁可以避免不必要的同步操作......
  • synchronized关键字的使用和原理
    在Java中,synchronized关键字是一种用于实现线程同步的机制,它可以确保在同一时刻只有一个线程能够访问被synchronized修饰的代码块或方法。一、作用和原理互斥访问:synchronized关键字通过对共享资源加锁来实现互斥访问。当一个线程进入synchronized代码块或方法时,它会获取......
  • 深入理解 synchronized 的锁升级【转载】
    目录本文转载自:前言锁升级无锁偏向锁轻量级锁重量级锁总要有总结锁优化本文转载自:深入理解synchronized的锁升级-掘金(juejin.cn)前言        最近看到一道有关synchronized关键字的面试题:不同JDK版本对synchronized有何优化?这道面试题的目......
  • WPF ListBox IsSynchronizedWithCurrentItem True ScrollIntoView via behavior CallM
    <ListBoxGrid.Column="0"ItemContainerStyle="{StaticResourcelbxItemContainerStyle}"ItemsSource="{BindingBooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"IsSynchronizedWith......
  • WPF ListBox IsSynchronizedWithCurrentItem="True"
    //xaml<Windowx:Class="WpfApp13.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.mic......