JavaRush /Java-Blog /Random-DE /Kaffeepause Nr. 171. So verwenden Sie das synchronisierte...

Kaffeepause Nr. 171. So verwenden Sie das synchronisierte Schlüsselwort. Dateiverwaltung in Java

Veröffentlicht in der Gruppe Random-DE

So verwenden Sie das synchronisierte Schlüsselwort

Quelle: Medium Heute erfahren Sie, in welchen Fällen und wie Sie das synchronisierte Schlüsselwort in der Programmiersprache Java richtig verwenden. Kaffeepause Nr. 171.  So verwenden Sie das synchronisierte Schlüsselwort.  Dateiverarbeitung in Java - 1Modifikatoren sind bestimmte in Java vorkommende Schlüsselwörter, mit deren Hilfe wir Änderungen an den Eigenschaften einer Variablen, Methode oder Klasse vornehmen und deren Umfang einschränken können. Die Java-Sprache verfügt über eine ziemlich große Menge an Modifikatoren. Modifikatoren werden in Java in zwei Typen unterteilt: Zugriffsmodifikatoren und Nichtzugriffsmodifikatoren .

Modifikatoren ohne Zugriff

Nicht zugängliche Modifikatoren versorgen die JVM mit Informationen über die Eigenschaften einer Klasse, Methode oder Variable. In Java gibt es sieben Arten von Nichtzugriffsmodifikatoren:
  • Finale
  • statisch
  • abstrakt
  • synchronisiert
  • flüchtig
  • vergänglich
  • einheimisch
In diesem Artikel werfen wir einen genaueren Blick auf das synchronisierte Schlüsselwort . Definieren wir zunächst, wo und wann es verwendet werden soll.

In welchen Fällen wird synchronisiert verwendet?

In Java wird das synchronisierte Schlüsselwort verwendet, um die Zugriffskontrolle auf eine Methode oder einen Codeblock bereitzustellen. Wenn ein Thread versucht, eine synchronisierte Methode oder einen synchronisierten Codeblock auszuführen, muss er zunächst eine Sperre erwerben. Sobald Sie die Sperre erhalten haben, können Sie mit der Ausführung beginnen. Allerdings wird jeder andere Thread, der versucht, dieselbe synchronisierte Methode oder denselben synchronisierten Codeblock auszuführen, blockiert, bis der erste Thread die Sperre aufhebt. Dadurch wird sichergestellt, dass jeweils nur ein Thread Code ausführen kann, was für die Aufrechterhaltung der Datenintegrität wichtig ist. Das synchronisierte Schlüsselwort kann sowohl mit statischen als auch mit nicht statischen Methoden sowie mit Codeblöcken verwendet werden.
  • Bei Verwendung mit statischen Methoden konkurrieren alle Threads um dieselbe Sperre. Dies kann sich auf die Leistung auswirken. Vermeiden Sie daher am besten die Synchronisierung statischer Methoden, sofern dies nicht unbedingt erforderlich ist.

  • Bei Verwendung mit nicht statischen Methoden verfügt jede Instanz der Klasse über eine eigene Sperre, sodass mehrere Threads gleichzeitig synchronisierten Code von verschiedenen Instanzen ausführen können. Dies ist normalerweise der bevorzugte Ansatz.

  • Bei Verwendung mit Codeblöcken wird eine Sperre für ein Objekt erworben, die an die synchronisierte Anweisung übergeben wird . Dadurch können mehrere Threads gleichzeitig synchronisierte Codeblöcke von verschiedenen Objekten ausführen.

Somit ist das synchronisierte Schlüsselwort ein leistungsstarkes Werkzeug zur Steuerung des gleichzeitigen Datenzugriffs in Java-Anwendungen. Bei richtiger Anwendung kann es dazu beitragen, die Datenintegrität sicherzustellen und die Leistung zu verbessern.

Anwendungsbeispiele

1. Synchronisierter Block

public class Counter {
  private int count = 0;

  public int getCount() {
    synchronized (this) {
      return count;
    }
  }

  public void increment() {
    synchronized (this) {
      count++;
    }
  }
}
Hier gibt es zwei Codeblöcke, die auf den Zähler zugreifen. Die einfachste davon ist die get- Methode , die einfach den Wert liest. Auf den ersten Blick scheint die Inkrementierungsmethode eine Codezeile zu enthalten. Denken Sie jedoch daran, dass die Inkrementierungsoperation den aktuellen Wert lesen, einen Wert hinzufügen und den neuen Wert zurück in den Speicher schreiben muss. Mit anderen Worten: Es gibt drei Unteroperationen, die wir ohne Unterbrechung durch andere Threads ausführen möchten. Platzieren Sie es beispielsweise auf der anderen Seite oder machen Sie die Inkrementierungsoperation atomar . Wenn wir zwei Codeblöcken das Schlüsselwort synchronisiert voranstellen , ist es wichtig zu beachten, dass wir sie auch als synchronisiert für ein bestimmtes Objekt markieren , wie in unserem Beispiel gezeigt. Das heißt, wenn wir mehrere Counter- Objekte haben , können verschiedene Threads diese verschiedenen Zähler gleichzeitig aktualisieren. Aber zwei Threads können nicht gleichzeitig synchronisierte Blöcke auf derselben Counter- Instanz ausführen .

2. Synchronisierte Methode

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}
Wenn count eine Instanz von SynchronizedCounter ist , hat die Synchronisierung dieser Methoden zwei Auswirkungen:
  • Erstens können sich zwei Aufrufe synchronisierter Methoden für dasselbe Objekt nicht verschachteln. Wenn ein Thread eine synchronisierte Methode für ein Objekt ausführt, halten alle anderen Threads, die synchronisierte Methoden für denselben Block des Objekts aufrufen, an, bis der erste Thread die Arbeit an dem Objekt abgeschlossen hat.

  • Zweitens: Wenn die synchronisierte Methode beendet wird, setzt sie den Wert bei allen nachfolgenden Aufrufen der synchronisierten Methode für dasselbe Objekt automatisch auf „passiert vor“ . Dadurch wird sichergestellt, dass Änderungen am Objektstatus für alle Threads sichtbar sind.

Denken Sie daran, dass das Wissen, warum, wie und wann synchronisierte und andere Modifikatoren verwendet werden sollen , mit Erfahrung einhergeht und Erfahrung mit der Zeit einhergeht.

Dateiverwaltung in Java

Quelle: Usemynotes Der Inhalt dieses Beitrags befasst sich mit der Dateiverarbeitung in Java. Sie werden mit Dateiverarbeitungsvorgängen, den Methoden der File-Klasse und den Stream-Typen vertraut gemacht. Kaffeepause Nr. 171.  So verwenden Sie das synchronisierte Schlüsselwort.  Dateiverarbeitung in Java - 2Die Arbeit mit Dateien ist ein wesentlicher Bestandteil jeder Programmiersprache. Mithilfe von Dateien kann ein Programm Daten auf einem Speichergerät speichern. Das Ausführen verschiedener Aktionen an einer Datei, z. B. Lesen oder Schreiben, erfordert die Verarbeitung der Datei. Unter Dateiverarbeitung versteht man das Lesen aus einer Datei und das Schreiben in eine Datei. Um ein Dateiobjekt zu erstellen und verschiedene Dateiformate zu verarbeiten, können wir die File- Klasse aus dem java.io- Paket verwenden . Wenn wir die File-Klasse verwenden möchten, müssen wir ein Objekt der File- Klasse erstellen und den Dateinamen oder Pfad angeben. Mit dieser Klasse können wir auf Dateimetadaten wie Dateiname, Dateigröße, Berechtigungen, Dateityp usw. zugreifen.
// importing all the classes of java.io
import java.io.*;
class FileHandle {
    public static void main(String[] arr) {
       // an object of File class is created.
       File f=new File("demo.txt");
}
}
Um die File- Klasse zu importieren, können Sie auch import java.io.File anstelle von import java.io.* verwenden . Lassen Sie uns nun etwas über Threads lernen, da Java Threads verwendet, um Eingabe-/Ausgabeoperationen (I/O) für eine Datei auszuführen.

Was ist ein Thread in Java?

Stream ist eine Folge von Daten. Es kann auch als eine Folge von Bytes definiert werden. Ein Stream kann verwendet werden, um entweder eine Eingabequelle oder ein Ziel darzustellen. Quelle und Ziel können Dateien auf der Festplatte, Arrays, Textdateien usw. sein. Der Eingabestream liest oder ruft Daten von der Quelle ab und der Ausgabestream schreibt Daten an das Ziel. Es gibt zwei Arten von Streams:

Byte-Stream

Ein Byte-Stream wird verwendet, um Lese- und Schreibvorgänge für Byte-Daten durchzuführen. Der Prozess der Verarbeitung einer Byte-Stream-Datei ist als Eingabe mithilfe von Byte-Daten definiert. Es gibt viele Klassen, die sich auf Bytestreams beziehen, aber die am häufigsten verwendeten Klassen sind FileInputStream und FileOutputStream .
import java.io.*;
public class FileHandle{
   public static void main(String []arr) throws IOException{
   FileInputStream fin=new FileInputStream("source_file.txt");
   FileOutputStream fout=new FileOutputStream("destination_file.txt");
   int character;
   while((character=fin.read())!=-1)
   {
      System.out.print((char)character);
      // writing to destination file
      fout.write((char)character);
   }
   // closing source_file.txt
   fin.close();
   // closing destination_file.txt
   fout.close();
 }
}
Im obigen Beispiel lesen wir Daten aus der Quelldatei und schreiben die Daten in das Ziel. -1 gibt das Ende der Datei an. Das Lesen aus der Quelldatei wird also beendet, wenn -1 angezeigt wird.

Charakterstrom

Character Stream wird verwendet, um Lese- und Schreibvorgänge für Zeichendaten durchzuführen. Der Prozess der Verarbeitung einer Datei mit einem Zeichenstrom ist der Prozess der Ausführung von Eingabedaten mit Zeichen. Es stehen viele Zeichenstromklassen zur Verfügung, aber zu den am häufigsten verwendeten Klassen gehören FileWriter und FileReader . Lassen Sie uns nun einige Methoden der File- Klasse besprechen .

Methoden der File-Klasse in Java

kann lesen()

Diese Dateiklassenmethode prüft, ob die Datei lesbar ist und gibt einen booleschen Wert zurück, also true oder false .

kann schreiben()

Dabei handelt es sich um eine Dateiklassenmethode, die prüft, ob eine Datei beschreibbar ist und einen booleschen Wert, also true oder false, zurückgibt.

existiert()

Dabei handelt es sich um eine Dateiklassenmethode, mit der die Existenz einer bestimmten Datei überprüft wird und die einen booleschen Wert zurückgibt.

createNewFile()

Wenn wir eine neue leere Datei erstellen möchten, verwenden Sie diese Dateiklassenmethode. Es gibt einen booleschen Wert zurück.

löschen()

Dies ist eine Dateiklassenmethode, mit der eine Datei gelöscht und ein boolescher Wert zurückgegeben wird.

getAbsolutePath()

Mit dieser Methode wird der absolute Pfad einer Datei zurückgegeben. getName() Dies ist eine Methode, die verwendet wird, um einen String-Wert zurückzugeben, der den Namen der Datei darstellt.

Liste()

Es gibt ein Array von Zeichenfolgen zurück, die alle Dateien im Verzeichnis darstellen.

Länge()

Diese Dateiklassenmethode gibt die Dateigröße in Bytes zurück.

mkdir()

Dies ist eine Dateiklassenmethode, die zum Erstellen eines neuen Verzeichnisses verwendet wird. Werfen wir einen Blick auf die verschiedenen in Java verfügbaren Dateioperationen und deren Verwendung.

Was sind Dateioperationen in Java?

Bei der Verarbeitung von Java-Dateien können wir die folgenden Vorgänge für eine Datei ausführen:
  • Erstellen einer Datei
  • Daten in eine Datei schreiben
  • Daten aus einer Datei lesen
  • Eine Datei löschen
  • Informationen zu einer Datei abrufen
  • Erstellen einer Datei
In Java können wir eine Datei mit der Methode createNewFile() der File- Klasse erstellen . Diese Methode gibt „true“ zurück , wenn die Datei erstellt wurde, andernfalls gibt sie „ false“ zurück , wenn die Datei bereits existiert.
import java.io.*;
public class FileHandle{
   public static void main(String []arr) throws IOException{
   // an object of file class
   File f=new File("demo.txt");
   // creating a new file
   Boolean result=f.createNewFile();
   if(result)
      System.out.print(f+" created successfully.");
   else
      System.out.format("%s","File cannot be created due to some error.");
 }
}

Daten in eine Datei schreiben

Ein Schreibvorgang in eine Datei bedeutet das Speichern von Daten in einer Datei. Um Schreibvorgänge für eine Datei auszuführen, verwenden wir die Methode write() zusammen mit der Klasse FileWriter . Um einen Stream zu schließen und zugewiesene Ressourcen zu erhalten, müssen wir die Methode close() verwenden .
import java.io.*;
public class FileHandle{
   public static void main(String []arr) throws IOException{
     // creating a new file and writing data to a file
     FileWriter fw=new FileWriter("demo.txt");
     String s="Welcome, this is tutorial of Java File Handling.";
     fw.write(s);
     // closing a file
     fw.close();
   }
}

Aus einer Datei lesen

Ein Lesevorgang bedeutet, auf in einer Datei gespeicherte Daten zuzugreifen oder diese abzurufen. Um einen Schreibvorgang für eine Datei durchzuführen, verwenden wir die Scanner-Klasse zusammen mit den Methoden hasNextLine() und nextLine() , um Daten aus der Datei abzurufen. Um einen Stream zu schließen, müssen wir die Methode close() verwenden .
import java.io.*;
import java.util.Scanner;
public class FileHandle{
   public static void main(String []arr) throws IOException{
     File f=new File("demo.txt");
     Scanner sc=new Scanner(f);
     while(sc.hasNextLine())
     {
       String str=sc.nextLine();
       System.out.println(str);
     }
     // closing a file
     sc.close();
   }
}

Eine Datei löschen

Bei der Verarbeitung von Java-Dateien können wir eine Datei mit der Methode delete() der Klasse File löschen . Es ist nicht erforderlich, die Datei mit der Funktion close() zu schließen , da die Klassen FileWriter und Scanner nicht zum Löschen der Datei verwendet werden .
import java.io.*;
public class FileHandle{
   public static void main(String []arr) throws IOException{
      File f=new File("demo.txt");
      Boolean result=f.delete();
      if(result)
         System.out.print(f+" deleted successfully.");
      else
         System.out.format("%s","File cannot be deleted due to some error.");
   }
}

Informationen zu einer Datei abrufen

In Java gibt es mehrere Methoden, um Informationen über eine Datei abzurufen. Sie wurden bereits weiter oben in den Methoden der Dateiklasse erwähnt.
import java.io.*;
public class FileHandle{
   public static void main(String []arr) throws IOException{
     File file=new File("demo.txt");
     file.createNewFile();
     String filename=file.getName();
     System.out.println("File Name is "+filename);
     System.out.println("Absolute path of "+filename+" : "+file.getAbsolutePath());
     System.out.print("length of "+filename+" : "+file.length());
     System.out.println("Is "+filename+" readable? "+file.canRead());
     System.out.println("Is "+filename+" writable? "+file.canWrite());
     System.out.println("Is "+filename+" exists? "+file.exists());
  }
}
Schauen wir uns an, wie ein Java-Programm bei der Verarbeitung von Java-Dateien mithilfe eines Byte-Array-Streams ermittelt, ob eine Zahl gerade oder ungerade ist. Um dieses Programm zu schreiben, verwenden wir die Klasse ByteArrayInputStream aus dem Paket java.io. Diese Klasse enthält einen Puffer, der zum Lesen eines Byte-Arrays als Eingabestream verwendet wird. Unten finden Sie den Code zum Überprüfen, ob Zahlen gerade oder ungerade sind.
import java.io.*;
public class FileHandle{
   public static void main(String []arr) throws IOException{
     byte []buffer={10,40,81,23,32,100,57};
     ByteArrayInputStream by=new ByteArrayInputStream(buffer);

     int character=0;
     while((character=by.read())!=-1)
     {
        int number=character;
        if(number%2==0)
          System.out.println(number+" is an even number.");
        else
          System.out.println(number+" is an odd number.");
     }
   }
}
Ich hoffe, dass die hier präsentierten Informationen für Sie nützlich waren. Um die Arbeit mit Dateien in Java besser zu verstehen, sollten Sie versuchen, alle Datei- und Betriebsmethoden selbst zu implementieren.
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION