オブジェクト指向プログラミング (JAVA) レビュー ノート (パート 2)

5. インターフェースとポリモーフィズム

インターフェース

インターフェイスは
、抽象クラスと同様に、複数のクラスの共通属性を
定義します。これにより、抽象化の概念がさらに深いレベルになります。これは「純粋な」抽象クラスであり、1 つの形式のみを提供し、次のこと
を可能にする基本的な実装は提供しません。 Form: 方法名参数列表および返回类型、ただし指定されていない には方法主体
、基本データ型のデータ メンバーも含めることができますが、それらはすべてデフォルトであり、staticすべてfinal
のメソッドは抽象メソッドであり、インターフェイス内のすべての属性は定数です。

インターフェースの役割
統一された開発標準(仕様)。インターフェイスは標準を定義し、このインターフェイスを使用するクラスは標準ユーザー、このインターフェイスを実装するクラスはこの標準のインプリメンタです。インターフェースの出現は、ユーザーと実装者の間の直接的な接続を間接的な接続に変換し、強い結合を弱い結合に変換して目的を達成します解耦
多重継承を実現し、同時にC++における多重継承の複雑さを回避する
抽象クラス統一開発標準だが、単一継承である

保険会社の例では、車両保険、個人保険、企業保険などのさまざまな保険事業を行っており
外部へのサービス提供において類似点があります空の三角形を含む点線はインターフェイスの構文を示します。(premium)Insurable

ここに画像の説明を挿入

宣言形式は次のとおりです

[接口修饰符] interface 接口名称 [extends 父接口名]{
    
    //方法的原型声明或静态常量
}

インターフェイスのデータ メンバーには初期値を割り当てる必要があり、この値は再度変更されません。final キーワードは省略できます。インターフェイス内のメソッドは「
抽象メソッド」である必要があり、メソッド本体を持つことはできません。 public キーワードと abstract キーワードは省略できます

インターフェースインスタンス:

インターフェイスと匿名内部クラスの実験

インターフェースの実装

インターフェイスは new 演算子を使用してオブジェクトを直接生成することはできません。その特性を使用して新しいクラスを設計し、
その新しいクラスを使用してオブジェクトを作成する必要があります。

public class 类名称 implements 接口名称 {
    
     
        /* Bodies for the interface methods */ 
        /* Own data and methods. */ 
}

知らせ:

  1. インターフェース内のすべてのメソッドを実装する必要がある
  2. インターフェースからのメソッドは次のように宣言する必要があります。public

オブジェクト変換
オブジェクトは、そのクラスによって実装されたインターフェイス型に変換できます。

例:
getPolicyNumberインターフェイスで宣言されたメソッドはCar クラスの新しく追加されたメソッドcalculatePremiumであり、このメソッドはインターフェイスでは宣言されていませんInsurable
getMileageInsurable

Car  jetta = new Car(); 
Insurable  item = (Insurable)jetta;   //对象转型为接口类型 
item.getPolicyNumber();
item.calculatePremium(); 
item.getMileage();           // 接口中没有声明此方法,不可以
jetta.getMileage();           // 类中有此方法,可以
((Car)item).getMileage(); // 转型回原类,可调用此方法了

多重継承

Java はシンプルかつ実用的になるように設計されています。クラスが複数の親クラスを持つことはできませんが
、クラスが複数のインターフェイスを実装することはできます。このメカニズムを通じて、多重継承を実現できます。クラスが複数のインターフェイスを実装するための構文は次のとおりです
。次のように

[类修饰符] class  类名称  implements 接口1,接口2,{
    
    
      … …
}

インターフェイスの拡張
インターフェイスの拡張
インターフェイスは、拡張テクノロジを通じて新しいインターフェイスを派生できます
元のインターフェイスが呼び出されます基接口(base interface)または父接口(super interface)
派生インターフェイスが呼び出されます派生接口(derived interface)または子接口(sub interface)
派生インターフェイスは、親インターフェイスのメンバーを保持するだけでなく、実際の問題に対処するために新しいメンバーを追加する 要件
インターフェイスを実装するクラスは、インターフェイスの親インターフェイスも実装する必要がある
インターフェイス拡張の構文

interface 子接口名称 extends 父接口名1,父接口名2,…
{
    
    
           … …
}

ここに画像の説明を挿入
Shape は親インターフェイスであり、Shape2D と Shape3D はそのサブインターフェイスです。Circle クラスと Rectangle クラスはインターフェイス Shape2D を実装し、Box クラスと Sphere クラスはインターフェイス Shape3D を実装します。

例:
ここに画像の説明を挿入
ここに画像の説明を挿入
実行:
ここに画像の説明を挿入

シェーピングは(type-casting)
、次のようなタイプ キャストとも呼ばれます

隐式(自动)的类型转换
显式(强制)的类型转换

形状オブジェクトには
プリミティブ データ型が含まれます

将值从一种形式转换成另一种形式

参照変数

将对象暂时当成更一般的对象来对待,并不改变其类型
只能被塑型为
	任何一个父类类型
	对象所属的类实现的一个接口
	被塑型为父类或接口后,再被塑型回其本身所在的类

例:
ここに画像の説明を挿入
暗黙的 (自動) 型変換

基本的なデータ型

相容类型之间存储容量低的自动向存储容量高的类型转换

参照変数

被塑型成更一般的类
Employee  emp; 
emp = new Manager(); //将Manager类型的对象直接赋给
 //Employee类的引用变量,系统会自动将Manage对象塑
//型为Employee类

オブジェクトが属するクラスによって実装されるインターフェイス型としてモデル化されます。

Car  jetta = new Car(); 
Insurable  item = jetta; 

明示的な (強制された) 型変換

基本的なデータ型

(int)871.34354;     // 结果为 871 
(char)65;              // 结果为‘A’ 
(long)453;            // 结果为453L

参照変数: 元の型に戻す

Employee  emp; 
Manager man;
emp = new Manager();
man = (Manager)emp; //将emp强制塑型为本来的类型

成形用途の例としては、

  1. 代入変換
    代入番号の右側の式の型またはオブジェクトを左側の型に変換します。
  2. メソッド呼び出し変換
    実引数の型を仮引数の型に変換します
  3. 算術式変換 算術
    混合演算時、異なる型の項目を同じ型に変換して演算します。
  4. 文字列変換
    文字列連結操作中に、一方のオペランドが文字列で、もう一方のオペランドが数値の場合、数値型は自動的に文字列に変換されます。

クラス オブジェクトがその親クラスとして整形されると、そのオブジェクトが提供するメソッドは減ります。オブジェクトが として整形されると
、メソッドは受信できますがメソッドは受信できません。元の型として整形された後は、メソッドを受信できるようになります。方法ManagerEmployeegetName()getEmployeeNumber()getSalary()
getSalary()

同じメソッドがプレキャスト クラスとポストキャスト クラスの両方で提供されている場合、メソッドがポストキャスト オブジェクトに送信された場合、システムはどのクラスを呼び出しますか?
実際の状況に応じて確認するには次の 2 つの方法があります。

实例方法的查找
类方法的查找

インスタンスメソッドの検索:

オブジェクトが作成されたときのクラスから始めて、クラス階層を調べます

Manager   man = new Manager(); 
Employee  emp1 = new Employee(); 
Employee  emp2 = (Employee)man; 
emp1.computePay(); // 调用Employee类中的computePay()方法 
man.computePay(); // 调用Manager类中的computePay()方法  
emp2.computePay(); // 调用Manager类中的computePay()方法 

ここに画像の説明を挿入
クラスメソッドの検索

参照先の変数が宣言されているクラスのルックアップ

Manager  man = new Manager(); 
Employee emp1 = new Employee(); 
Employee emp2 = (Employee)man; 
man.expenseAllowance();          //in Manager 
emp1.expenseAllowance();         //in Employee 
emp2.expenseAllowance();         //in Employee!!! 

ここに画像の説明を挿入

多態性

ポリモーフィズムとは、異なるタイプのオブジェクトが同じメッセージに応答し、同じ動作を実行し、異なる動作特性を示すことができることを意味します。
同じ基本クラスから派生した複数の型は同じ型として扱うことができ、これらの異なる型も同様に扱うことができます。ポリモーフィズムにより、同じメソッドに応答するときのこれらの異なる派生クラス オブジェクトの動作は異なります。

例えば

所有的Object类的对象都响应toString()方法
所有的BankAccount类的对象都响应deposit()方法

ポリモーフィズムの目的
すべてのオブジェクトを同じ型に整形し、同じメッセージに応答できる
コードをシンプルで理解しやすくする
プログラムを「拡張可能」にする

ポリモーフィズムの一般的な形式
ここに画像の説明を挿入
ポリモーフィズムの前提条件

有继承/实现关系;
有父类引用指向子类对象;
有方法重写。

一例:

描画 - 直接的な方法
サブタイプ オブジェクトの形状を描画できるようにしたい場合は、Shapeクラス内で複数の描画メソッドを宣言し、実際のオブジェクトごとに異なる描画メソッドを使用できます。

if (aShape instanceof Circle)        aShape.drawCircle(); 
if (aShape instanceof Triangle)    aShape.drawTriangle(); 
if (aShape instanceof Rectangle)  aShape.drawRectangle();

ここに画像の説明を挿入


描画 -各サブクラスで同じ名前のdraw()メソッドを宣言するより良い方法 (ポリモーフィズム) で
、次のように描画を実行できます。

Shape s = new Circle(); 
s.draw();

Circle は Shape の一種であり、システムは自動的に整形を実行します。draw
メソッドが呼び出されるとき、Circle.draw()
プログラムの実行中にバインディングが実際に呼び出されます。次に、バインディングの概念が導入されます。
ここに画像の説明を挿入
バインディングとは、メソッドを呼び出すことを指します。同じメソッド本体を接続する
結合期間に応じて、次のように分けることができます

早期绑定
	程序运行之前执行绑定
晚期绑定
	也叫作“动态绑定”或“运行期绑定”
	基于对象的类别,在程序运行时执行绑定

例:
ここに画像の説明を挿入
ここに画像の説明を挿入
ポリモーフィズムの応用
技術基盤
上向き整形技術:親クラスの参照変数は異なるサブクラスオブジェクトを指すことができる
動的バインディング技術:親クラスの参照変数が指すオブジェクトの実際の型に応じて、対応するサブクラスを実行実行時メソッドによりポリモーフィズムを実現

コンストラクターと多態性
コンストラクターは他のメソッドとは異なります
。 コンストラクターは多態性ではありませんが、複雑な階層で多態性を伴うコンストラクターをどのように使用できるかを理解することは依然として非常に重要です。

コンストラクターが呼び出される順序

  1. 基本クラスのコンストラクターを呼び出す
  2. メンバーコンストラクターを宣言順に呼び出す
  3. 自己コンストラクターを呼び出す

派生クラスを構築するときは、基本クラスのすべてのメンバーが有効であると想定できなければなりません。
コンストラクター内では、使用されるすべてのメンバーが初期化されることが保証される必要があります。
したがって、唯一の方法は、最初に基本クラスのコンストラクターを呼び出し、次に、派生クラスのコンストラクターに入る前に、アクセス可能なすべてのメンバーを初期化することです。

構築メソッド内の多態性メソッド
構築メソッド内で構築されるオブジェクトの動的バインディング メソッド (抽象メソッド - 抽象クラス/インターフェイス) を呼び出すと、
派生クラスにあるメソッドが呼び出されます
呼び出されたメソッドによって操作されるメンバは、まだ取得されていません 正しい初期化により、
見つけにくいプログラム エラーが発生する可能性があります

内部クラス

内部クラス
別のクラスまたはメソッドの定義内で定義されたクラス
外部クラス内のすべてのデータおよびメソッド メンバーにアクセスできる
論理的に関連するクラスをグループ化できる
同じパッケージ内の他のクラスから隠すことができるイベント駆動型プログラムを
非常に簡単に作成できる

声明

命名的内部类:可在类的内部多次使用
匿名内部类:可在new关键字后声明内部类,立即创建一个对象

外部クラス名が Myclass であるとすると、このクラスの内部クラス名は次のようになります。

Myclass$c1.class (c1为命名的内部类名)
Myclass$1.class (表示类中声明的第一个匿名内部类)

内部クラスによって実装されたインターフェイスは
まったく表示されず、呼び出すこともできない
ため、「隠された実装の詳細」の実装が容易になります。取得できるのは基本クラスまたはインターフェイスへの参照だけです


メソッド内の内部クラス
メソッド内の内部クラスを定義する インターフェイスを実装するには、参照を生成して返します。
複雑な問題を解決するには、クラスを作成する必要がありますが、それが外部で使用されることは望ましくありません。

6. I/O とファイル

入力ストリームと出力ストリーム (java.io)

入力ストリーム
情報ソースから情報を取得するために、プログラムは入力ストリームを開き、入力ストリームから情報を読み取ることができます。 出力ストリーム プログラムが
ターゲット
の場所に情報を書き込む必要がある場合、出力ストリームを開く必要があります。 、プログラムは出力ストリーム情報を通じてターゲットの場所に書き込みます

入出力の流れは以下の観点から分類できます。
流れの方向から

输入流
输出流

ストリームの分割から

节点流
处理流

ストリームの内容から切り離す

面向字符的流
面向字节的流

文字指向ストリーム: 文字データ専用に使用されます。
バイト指向ストリーム: 汎用目的に使用されます。

キャラクター指向のストリーム

文字指向ストリーム
文字データの特性に合わせて最適化され、いくつかの便利な文字指向機能を提供
ソースまたは宛先は通常、テキスト ファイルです

文字指向の抽象クラス --ReaderそしてWriter

java.io包中所有字符流的抽象基类
Reader提供了输入字符的API
Writer提供了输出字符的API

それらのサブクラスは 2 つのカテゴリに分類できます

节点流:从数据源读入数据或往目的地写出数据
处理流:对数据执行某种处理

ほとんどのプログラムは、テキスト情報の読み取り/書き込みに、これら 2 つの抽象クラスの一連のサブクラスを使用します。
たとえば、テキスト ファイルの読み取り/書き込みには、FileReader/FileWriter が使用されます。
ここに画像の説明を挿入

バイト指向のストリーム

InputStreamおよび はOutputStream
、8 ビット バイト ストリームの処理に使用される抽象基本クラスです。プログラムは、これら 2 つのクラスのサブクラスを使用して、8 ビット バイト情報の読み取りと書き込みを行います。プログラムは 2 つの部分に分かれてい
ます

节点流
处理流

標準入出力ストリーム

標準の入出力ストリーム オブジェクトには
System类的静态成员变量
次のものがあります。

System.in: 標準入力ストリームを表す InputStream タイプ。このストリームは開かれており、デフォルト状態はキーボード入力に対応します。
System.out: PrintStream 型、標準出力ストリームを表し、デフォルト状態は画面出力に対応します。
System.err: PrintStream 型、標準エラーメッセージ出力ストリームを表し、デフォルト状態は画面出力に対応します

System.in は、プログラムの開始時に Java システムによって自動的に作成されるストリーム オブジェクトです。これはプリミティブなバイト ストリームであり、そこから文字を直接読み取ることはできません。パラメータのストリーム オブジェクトを作成する
にはさらに処理する必要があります。はバイト ストリームと同等です。バイト ストリームを読み取って文字に変換する、 と 文字ストリームの間のブリッジです。
InputStreamReader(System.in)
System.inInputStreamReader

BufferedReader in
処理された情報をバッファリングしInputStreamReaderて効率を向上させる

IO 例外
ほとんどの IO メソッドはエラーが発生すると例外をスローするため、これらのメソッドを呼び出すときは、メソッド ヘッダーで例外の
スローを宣言するか、try ブロックで IO を実行してからキャプチャする必要があります。throws IOException
catch IOException

書類

File オブジェクトを指定して FileWriter オブジェクトを構築します。

 FileWriter(File file, boolean append)

データを書き込むかどうかを示すブール値が追加された、ファイル名を指定して FileWriter オブジェクトを構築します。

FileWriter(String fileName, boolean append)

方法:

public void write(int c) throws IOException

単一の文字を書きます c

public void write(char [] c, int offset, int len)

offset から始まり len の長さの文字配列の一部を書き込みます。

public void write(String s, int offset, int len)

offset から始まり len の長さの文字列の一部を書き込みます。

例:

実験6

ここに画像の説明を挿入

FileReader クラス
テキスト ファイルから文字を読み取ります。抽象クラスBufferedReaderのサブクラス
から継承されます。 テキスト ファイルを読み取るためのバッファ クラスです。 改行を識別し、入力ストリームの内容を 1 行ずつ読み取ることができるメソッドを持ちます。 Reader から継承されます。ReaderInputStreamReader


readLine()

バイナリーファイル

例:

実験7

ここに画像の説明を挿入
ここに画像の説明を挿入

ファイルクラス

ディスク ファイル情報を表します
ファイルを操作するためのプラットフォームに依存しないメソッドをいくつか定義します

创建、删除文件
重命名文件
判断文件的读写权限及是否存在
设置和查询文件的最近修改时间等

ファイル ストリームの構築では、File クラスのオブジェクトをパラメータとして使用できます。

ここに画像の説明を挿入
クラス java.io.File
ファイルとパスに関するさまざまな役立つ情報を提供します
ファイルを開いたり、ファイルの内容を処理したりしません
例:

  File f1 = new File("/etc/passwd"); 
  File f2 = new File("/etc", "passwd"); 

ここに画像の説明を挿入
上下のフォルダーは区切り文字で区切られます。Windows
の区切り文字は\、Unix/Linux の区切り文字は です/より専門的なアプローチは、
クロスプラットフォーム ディレクトリ区切り文字を使用することです。この値は、システムによって取得された対応する区切り文字に基づきます。
File.separatorChar

例:new File("c:" + File.separatorChar + "a.txt");

注:
「"を使用する場合はエスケープして「\」と記述する必要があります。「"が2つある場合は「\\」と記述してください。

ここに画像の説明を挿入
この章の残りの部分は省略されており、実験内容をマスターするだけにしてください。(定期試験のこの部分は重要なポイントではないため、ここでは多くの部分を省略しています。必要に応じて他のブログを参照してください)

7、配列コレクション

オブジェクトの配列

まず、自然ソートとカスタムソートという2 種類のソートについて理解します。

ここに画像の説明を挿入

配列 オブジェクト シーケンスを格納し、ランダムにアクセスするために Java が提供するさまざまなメソッドの中で、配列
が最も効率的です。

类型检查
边界检查

アドバンテージ

数组知道其元素的类型
编译时的类型检查
大小已知

料金

数组对象的大小是固定的,在生存期内大小不可变

オブジェクトの配列

数组元素是类的对象
所有元素具有相同的类型
每个元素都是一个对象的引用

ここに画像の説明を挿入
コレクションとは、
同じ性質を持つものを集めて全体にしたものです

Java コレクションには基本的なデータ型は保存できませんが、オブジェクトのみを保存できます。
これらは、コレクション フレームワークと呼ばれる、コレクション インターフェイスとマップ インターフェイスをルートとする階層に編成されます。

コレクション フレームワーク (Java Collections Framework) は、コレクションを表現および操作する
ための統一された標準アーキテクチャを提供します。これは、使用できる既製のデータ構造をいくつか提供します。プログラマーは、コレクション フレームワークを使用して、コードをすばやく記述し、優れたパフォーマンスを得ることができます。これには、次の 3 つのチャンクが含まれています。コンテンツ

对外的接口:表示集合的抽象数据类型,使集合的操作与表示分开
接口的实现:指实现集合接口的Java类,是可重用的数据结构
对集合运算的算法:是指执行运算的方法,例如在集合上进行查找和排序

コレクション フレームワーク インターフェイスは、 Collection、Set、List、SortedSet、Map、SortedMap などの
さまざまなコレクション タイプに対して実行される一般的な操作を宣言します。 Java コレクションには、 、 、 の 3 つのタイプが含まれます

Set(集)List(列表)Map(映射)

java.utilすべての Java コレクション クラスはパッケージ内にあります。

Java コレクション フレームワーク - コレクション インターフェイス

Collectionインターフェイス
宣言ではパラメータ型を使用できます。つまり、Collection<E>(ジェネリック型) は
バッチ オブジェクトを操作する一連の抽象メソッドを宣言します:クエリ メソッド、変更メソッド
クエリ メソッド

int size() – 返回集合对象中包含的元素个数
boolean isEmpty() – 判断集合对象中是否还包含元素,如果没有任何元素,则返回true
boolean contains(Object obj) – 判断对象是否在集合中
boolean containsAll(Collection c) –判断方法的接收者对象是否包含集合中的所有元素

変更方法としては、

boolean add(Object obj) – 向集合中增加对象
boolean addAll(Collection<?> c) – 将参数集合中的所有元素增加到接收者集合中
boolean remove(Object obj) –从集合中删除对象
boolean removeAll(Collection c) -将参数集合中的所有元素从接收者集合中删除
boolean retainAll(Collection c) – 在接收者集合中保留参数集合中的所有元素,其它元素都删除
void clear() – 删除集合中的所有元素

Java コレクション フレームワーク - Set、SortedSet インターフェイス

Set インターフェイスは
Collection を拡張して要素の
繰り返しを禁止し、数学における "set" の抽象化です。合計演算
のためのより強力なequals規約があります。2 つの Set オブジェクトに同じ要素が含まれている場合、それらはそれを実装する 2 つのメイン クラスhashCodeと同等です。
そして哈希集合(HashSet)_树集合(TreeSet)

SortedSet インターフェース要素が配置され、関連する操作が追加された
特別なセット通常、語彙などのコンテンツを格納するために使用されます
升序次序

Setの一般的な使用法 Setここに画像の説明を挿入
の例:

Set<String>  set=new HashSet<String>();
String  s1=new  String(Hello);
String  s2=new  String(Hello); 
String  s3=new  String(World);
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set.size());   //对象的数目为2

HashSet クラス
HashSet クラスは、ハッシュ アルゴリズムに従ってコレクション内のオブジェクトにアクセスし、アクセスと検索のパフォーマンスが優れています。
オブジェクトをコレクションに追加すると、HashSet はhashCode()オブジェクトのメソッドを呼び出してハッシュ コードを取得し、ハッシュ コードに従ってコレクション内のオブジェクトの位置をさらに計算します。

ハッシュ(一般にハッシュとして翻訳、ハッシュ化、または音訳される) は、ハッシュ アルゴリズム を通じて任意の長さの入力を固定長の出力散列変換することであり、出力はハッシュ値です。この変換は圧縮マップです。つまり、ハッシュ値のスペースは通常、入力のスペースよりもはるかに小さくなります。異なる入力が同じ出力にハッシュされる可能性があるため、ハッシュ値から一意の入力値を決定することは不可能です。ハッシュアルゴリズムはハッシュアルゴリズムとも呼ばれますが、ハッシュアルゴリズムはアルゴリズムと呼ばれていますが、実際にはアイデアに近いものです。ハッシュ アルゴリズムには決まった公式はなく、ハッシュの考え方に準拠している限り、ハッシュ アルゴリズムと呼ぶことができます。


ハッシュも参照

イテレータクラス

Iterableインターフェイス: このインターフェイスを実装するコレクション オブジェクトは反復をサポートしており、foreach で使用できます。
Iterator : イテレータ、反復メカニズムを提供するオブジェクト、および反復方法は Iterator インターフェイスによって指定されます。hasNext、next、remove の 3 つのメソッドが含まれています。
コレクション内の要素が並べ替えられていない場合、反復子がコレクション内の要素を走査する順序は任意であり、要素がコレクションに追加される順序と必ずしも一致しない可能性があります。

public interface Iterable<T>
{
    
    
        Iterator<T> iterator();
}

イテレータ関数は比較的単純で、一方向にのみ移動できます。
使用方法では、iterator()コンテナが 1 を返す必要がありますIteratorこのメソッドが初めて呼び出されるときIteratornext()シーケンスの最初の要素が返されます。注:メソッドはインターフェイスiterator()に属し、継承されます。シーケンス内の次の要素を取得するために使用します。シーケンス内にさらに要素があるかどうかを確認するために使用します。新しく返された要素をイテレータから削除するために使用します。Iterator は Java イテレータの最も単純な実装です。List 用に設計された ListIterator には、より多くの機能があります。List を 2 方向から走査でき、List の要素を挿入および削除することもできます。java.lang.IterableCollection
next()
hasNext()
remove()

ツリーセットクラス

TreeSet クラスは、SortedSetコレクション内のオブジェクトを並べ替えることができるインターフェイスを実装します。
ここに画像の説明を挿入
オブジェクトがコレクションに追加されると、そのオブジェクトは順序付けられたオブジェクトのコレクションに挿入されます。
TreeSet は 2 つの並べ替え方法をサポートしています。

自然排序
客户化排序

デフォルトで採用されます自然排序

ナチュラルソート

式の場合x.compareTo(y)

如果返回值为0,则表示x和y相等
如果返回值大于0,则表示x大于y
如果返回值小于0,则表示x小于y

TreeSet は、compareTo()オブジェクトのメソッドを呼び出して、コレクション内のオブジェクトのサイズを比較し、昇順に並べます。このメソッドは、ナチュラル ソートと呼ばれます。通常は昇順でソートされますが、 JDK クラス ライブラリの Comparable インターフェイスを実装する一部のクラスのソート メソッドでは、
return の前に負号を追加することで降順でソートできます。自然な並べ替えを使用する場合、同じタイプのオブジェクトのみを TreeSet コレクションに追加でき、これらのオブジェクトはインターフェイスを実装する必要があります。

ここに画像の説明を挿入
Comparable

ここに画像の説明を挿入

カスタム並べ替え
Java.util.Comparator<Type>インターフェイスは、特定の並べ替え方法を提供し、<Type>比較するオブジェクトの種類を指定し、2 つのオブジェクトのサイズを比較する方法をComparator備えています。比較(x, y)compare(Type x,Type y)

返回值为0,则表示x和y相等
如果返回值大于0,则表示x大于y
如果返回值小于0,则表示x小于y

Student オブジェクトの name 属性に従って TreeSet を降順で並べ替える場合は、まず Comparator インターフェイスを実装する StudentComparator クラスを作成します。
StudentComparator クラスはカスタム コンパレータです。

パブリックネイティブ int hashCode()

デフォルトでは、オブジェクトの 32 ビット JVM メモリ アドレスを返します
「クラス ハッシュ テーブル」を作成する場合にのみ、クラスは他の場合 (たとえば、クラスの単一オブジェクトの作成hashCode()
またはクラスのオブジェクトの配列を作成するなど)、クラスはhashCode() 効果がありません。
ハッシュ テーブルは、HashMap、Hashtable、HashSet など、本質的にハッシュ テーブルである Java コレクション内のクラスを指します。

HashSet を例として、hashCode() の機能を詳しく説明します。
ここに画像の説明を挿入hashCode()とequals()の関係

  1. 「クラスに対応したハッシュテーブル」は作成しません
    ここに画像の説明を挿入
  2. 「クラスに対応したハッシュテーブル」を作成します
    ここに画像の説明を挿入

Java コレクション フレームワーク - リスト インターフェイス

List インターフェイスは、
Collection インターフェイスを拡張して、
繰り返しの要素を含めます。要素は順序付けされており
各要素には、リスト内の要素の位置を示す値 (0 から始まります) があります。パラメータを使用して宣言できます。つまり、4 つの主な実装です。クラスindex
List<E>

Vector
ArrayList:一种类似数组的形式进行存储,因此它的随机访问速度极快
LinkedList:内部实现是链表,适合在链表中间需要频繁进行插入和删除操作
栈Stack

ここに画像の説明を挿入
リストの並べ替えリストでは、インデックス順に従って
コレクション内のオブジェクトを並べ替えることしかできません。他の特定の方法でリスト内のオブジェクトを並べ替えたい場合は、インターフェイスとクラスを使用できます。Collections クラスは、Java コレクション クラス ライブラリの補助クラスであり、コレクションを操作するためのさまざまな静的メソッドを提供します。: リスト内のオブジェクトを自然に並べ替えます。: リスト内のオブジェクトに対してカスタム並べ替えを実行し、パラメータで並べ替え方法を指定します。ComparatorCollections

sort(List list)
sort(List list,Comparator comparator)comparator

Java コレクション フレームワーク - Map、SortedMap インターフェイス

Map インターフェイスは
、Collection インターフェイスの継承ではありません。キーと値のペア (キー/値ペア) を維持して、非反復キーから値へのマッピングを記述するために
使用されます。キーワードから値へのマッピング オブジェクトです。キーワード キーを繰り返すことはできません。各キーワードは最大 1 つの値にマップできます。キーワードは2つのパラメータで宣言できます。つまり、K はキーワードのタイプを表し、V は値のタイプを表します。SortedMapインターフェイスキーワードが昇順に配置されたマップ 通常、辞書や電話帳などで使用される同等のマップは、2つのパラメータ、すなわち で宣言できます。ここで、K はキーワードのタイプを表し、V はキーワードのタイプを表します。値


Map<K, V>


SortedSet
SortedMap<K, V>

マップ (マッピング) : コレクション内の各要素には、キー オブジェクトと値オブジェクトのペアが含まれます。コレクション内で繰り返されるキー オブジェクトはなく値オブジェクトは繰り返すことができます

ここに画像の説明を挿入
Map コレクションに要素を追加するときは、キー オブジェクトと値オブジェクトのペアを指定する必要があります。Map:と の
2 つの主要な実装クラスHashMapTreeMap

Map の最も基本的な使用法は、同様の字典機能を提供することです。
Map 内の要素を取得するときは、それが指定されている限り键对象、取得されます返回值对象

public Set keySet(): 返回键的集合。
public Set<Map.Entry<k,v>> entrySet(): 返回“键值对”的集合。
//Map.Entry的对象代表一个“词条”,就是一个键值对。可以从中取值或键。

HashMapハッシュ アルゴリズムに従ってキー/値オブジェクトにアクセスします。メソッドによって2 つのキー オブジェクトが true と比較されたときに、正常に同じように動作することを
保証するために、 2 つのキー オブジェクトのメソッドによって返されるハッシュ コードも同じになります。HashMapHashSetequals()hashCode()

Map と Map.Entry の詳細説明
ここに画像の説明を挿入TreeMap は、キー オブジェクトを並べ替えることができる SortedSet インターフェイスを実装しています。自然な並べ替えとカスタム並べ替えをサポートします。

インターフェースの実装

ここに画像の説明を挿入

ベクター

ベクター (ベクター、配列リスト)

实现了Collection接口的具体类
能够存储任意对象,但通常情况下,这些不同类型的对象都具有相同的父类或接口
不能存储基本类型(`primitive`)的数据,除非将这些数据包裹在包裹类中
其容量能够根据空间需要自动扩充
增加元素方法的效率较高,除非空间已满,在这种情况下,在增加之前需要先扩充容量

Vector メソッドは同期であり、スレッドセーフ
ArrayListメソッドは非同期であり、より効率的です。

Vector クラスは、オブジェクトの動的配列を実装できます。ArrayList とほぼ同じです。
Vector はあらゆる面で優れたパフォーマンスを備えているわけではないため、現時点での使用はお勧めしません

コレクションの横断

4 つの走査方法
for ループの走査を強化します。
ここに画像の説明を挿入

ハッシュ表

ここに画像の説明を挿入

8、スレッド

マルチスレッドプログラミングの基礎

マルチプログラミングでは、
複数の独立したプログラムをコンピューターのメモリに同時に保存し、監視プログラムの制御下で相互に散在して実行します。コンピュータシステムにおいて、起動から終了までの間、複数のプログラムが同じ状態にある状態。

マルチプログラミング技術の動作の特徴

多道
宏观上并行
微观上串行(单核CPU)

プログラムの同時実行
論理的に独立したプログラムまたはプログラム セグメントのグループの実行時間が、実行プロセス中に客観的に重複します。つまり、1 つのプログラム セグメントの実行がまだ終了しておらず、別のプログラム セグメントの実行が開始されています。

プログラムを同時に実行すると、次のような特徴があります。

间断性
失去封闭性
不可再现性

プロセスの定義
プロセスは、特定のデータ セットに対して特定の独立した機能を備えたプログラムの実行アクティビティです。これは、オペレーティング システムがリソースを割り当てることができる単位です。

プロセス特性

结构特征
动态性
并发性
独立性
异步性

スレッドの定義は
线程(thread)、オペレーティング システムが CPU 動作のスケジューリングを実行できる最小単位です。
これはプロセスに含まれており、プロセス内の実際の操作単位となります。
スレッドは、プロセス内の制御フローの単一シーケンスを指します。複数のスレッドが 1 つのプロセス内で同時に実行でき、各スレッドは異なるタスクを並行して実行します。

减少开销
提高效率

プロセス: 同時に実行されるプログラムの実行中にリソースを割り当て、管理するための基本単位であり、動的概念であり、コンピュータ システム リソースを争うための基本単位です。
スレッド: プロセスの実行単位であり、オペレーティング システムが操作のスケジューリングを実行できる最小単位です。スレッドは軽量プロセスとしても知られています。

プログラムには少なくとも 1 つのプロセスがあり、プロセスには少なくとも 1 つのスレッドがあります。

なぜスレッドがあるのですか?

各プロセスには独自のアドレス空間、つまりプロセス空間があります。ネットワークまたはマルチユーザー スイッチの下では、サーバーは通常、不確実な数のユーザーからの大量のリクエストを同時に受信する必要があります。各要求に対するプロセス (システムのオーバーヘッド、ユーザー要求に対する大量の応答は非効率的) のため、オペレーティング システムにスレッドの概念が導入されます。

プロセススレッドの違い:

  1. 地址空间: 同じプロセスのスレッドはプロセスのアドレス空間を共有しますが、プロセス間のアドレス空間は独立しています。
  2. 资源拥有: 同じプロセス内のスレッドは、メモリ、I/O、CPU などのプロセスのリソースを共有しますが、プロセス間のリソースは独立しています。
  3. プロセスがクラッシュしても、保護モードの他のプロセスには影響しませんが、スレッドがクラッシュするとプロセス全体が停止します。したがって、マルチプロセッシングはマルチスレッドよりも堅牢です
  4. プロセスを切り替えると、多くのリソースが消費され、効率が高くなりますしたがって、頻繁に切り替える場合には、プロセスよりもスレッドを使用する方が適しています。同様に、同時に実行する必要があり、特定の変数を共有する同時操作の場合、プロセスの代わりにスレッドのみを使用できます。
  5. 実行プロセス: それぞれの独立したプロセスには、プログラム実行エントリ、順次実行シーケンス、およびプログラム エントリがあります。ただし、スレッドは独立して実行できず、アプリケーション プログラムに依存する必要があり、アプリケーション プログラムは複数のスレッドの実行制御を提供します。
    スレッドはプロセッサ スケジューリングの基本単位ですが、プロセスはそうではありません。
  6. 両方を同時に実行できます。

プロセスの 3 つの基本状態とその遷移
ここに画像の説明を挿入
ブロック:
特定の関数またはプロセスを実行し、特定のイベントの発生を待った後、プログラムが CPU 占有を一時的に停止する状況、つまり CPU アイドル状態です。

スレッドの使用を検討する必要があるのはどのような場合ですか?
ここに画像の説明を挿入
スレッドを使用する利点は次のとおりです。

  1. スレッドを使用すると、プログラム内の長時間かかるタスクをバックグラウンドで処理できます。

  2. ユーザー インターフェイスはより魅力的なものにすることができ、たとえば、ユーザーがボタンをクリックして特定のイベントの処理をトリガーすると、プログレス バーがポップアップして処理の進行状況を表示できます。

  3. プログラムの実行速度が速くなる可能性があります。

  4. ユーザー入力、ファイルの読み取りと書き込み、ネットワークでのデータの送受信などの待機中のタスクの実装では、スレッドの方が便利です。この場合、メモリ使用量などの貴重なリソースの一部が解放される可能性があります。

  5. ……

例:
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
最もマルチスレッドなシナリオ:

Web サーバー
さまざまな専用サーバー (ゲーム サーバーなど)
のバックグラウンド タスク(定期的な間隔で多数のユーザー (100 ワット以上) に電子メールを送信するなど)
非同期処理 (Weibo の送信、ログの記録など)
分散コンピューティング、高パフォーマンスパフォーマンスコンピューティング

プログラム、プロセス、スレッド

程序(Program): これは静的コードの一部であり、アプリケーション ソフトウェア実行の設計図です。
进程(Process): プログラムの実行プロセスであり、システムがプログラムを実行するための基本単位であり、システムがリソースを割り当てて管理するための最小単位です。オペレーティングシステム上では複数のタスク(プログラム)を同時に実行することができますが、
线程(Thread)プロセスよりも小さな実行単位であり、タスク内の実行パスに相当し、システム動作のスケジューリングの最小単位となります。同じアプリケーション内で同時に実行される複数のシーケンス フローがあります。

マルチスレッドの目的は、CPU リソースの使用を最大限に活用することです。

Java でマルチスレッドを実装するには 2 つの方法があります。

  1. java.langパッケージ内のクラスを継承しますThread
  2. ユーザーは、自分自身を定義するクラスにインターフェースを実装しますRunnable

java.lang パッケージの Thread クラスを継承する

Thread类Object クラスを直接継承し、Runnableインターフェイスを実装します。java.langパッケージ内にあります
スレッド オブジェクトに必要なプロパティとメソッドをカプセル化します
継承Threadクラス - マルチスレッドを作成するメソッドの 1 つ クラス
からサブクラスThreadを派生し、サブクラスのオブジェクトを作成します サブクラスは、クラスのメソッドをオーバーライド
する必要があります。また、書き込みはスレッド内で実行される新しいステートメントセグメントに行う必要があります。メソッドを呼び出して新しいスレッドを開始すると、自動的にメソッドに入ります。Threadrun
startrun

Thread のサブクラスを定義し、次のようにその run メソッドをオーバーライドします。

class MyThread extends Thread {
    
    
         @Override
            public void run() {
    
    ...}
 }

このクラスのオブジェクトを作成します。

MyThread myThread = new MyThread();

スレッドを開始または実行すると、Java 仮想マシンは自動的にスレッドを開始します。これにより、Java 仮想マシンはスレッドをさらに均一にスケジュールできるようになり、すべてのスレッドが同時に同時に実行できるようになります。

public void start()
myThread.start();

例:

public class ThreadCreateDemo1 {
    
    
    public static void main(String[] args) {
    
    
        MyThread thread = new MyThread();
        thread.start(); //该方法调用多次,出现IllegalThreadStateException
    }
}

class MyThread extends Thread {
    
    
    @Override
    public void run() {
    
    
        super.run();
        System.out.println("hellow_world!");
    }
}

Runnableインターフェイスを実装する

Runnable インターフェイスは、インターフェイス
Thread类を実装します。 run() メソッドは 1 つだけあり、複数のスレッドがリソースを共有するのに便利です。Java は多重継承をサポートしていません。特定の基本クラスを継承している場合は、Runnable インターフェイスを実装する必要があります。複数のスレッドを生成するrunnable を実装したオブジェクトをパラメータとして設定する new threadメソッドはスレッドを開始し、メソッドを実行しますRunnable




startrun()

例:

public class ThreadCreateDemo2 {
    
    
    public static void main(String[] args) {
    
    
        Runnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
    }
}

class MyRunnable implements Runnable {
    
    
    public void run() {
    
    
        System.out.println("通过Runnable创建的线程!");
    }
}

Thread の継承と Runnable インターフェイスの実装の違いは次のとおりです。

a.实现Runnable接口避免多继承局限
b.实现Runnable()可以更好的体现共享的概念

スレッド間でのデータ共有

Runnableインターフェイスをパラメータとして実装する同じオブジェクトを使用して複数のスレッドを作成する 複数のスレッドが
同じオブジェクト内の同じデータを共有する

独立して同時に実行されるスレッドは、一部のデータを共有し、互いの状態とアクションを考慮する必要がある場合がありますこのように、データ相互干渉(共有データエラー)の問題が発生します。

同時プログラミング

マルチスレッド同期制御

スレッドが互いに独立していないため、同期する必要がある場合があります。

スレッド間の相互排他

同时运行的几个线程需要共享一个(些)数据
共享的数据,在某一时刻只允许一个线程对其进行操作

「生産者と消費者」の問題

假设有一个线程负责往数据区写数据,另一个线程从同一数据区中读数据,两个线程可以并行执行
如果数据区已满,生产者要等消费者取走一些数据后才能再写
当数据区空时,消费者要等生产者写入一些数据后再取

スレッドの同期 同期
互斥: 多くのスレッドが互いに干渉することなく同じ共有データ上で動作し、同時に 1 つのスレッドのみが共有データにアクセスできます。したがって、一部のメソッドまたはプログラム セグメントは同時に 1 つのスレッドでしか実行できません。これをモニター領域 (クリティカル領域)と呼びます。
协作: 複数のスレッドが条件付きで共有データを同時に操作できます。モニター領域でコードを実行しているスレッドは、条件が満たされていれば、他のスレッドがモニター領域に入るのを許可できます。

マルチスレッドのスレッド同期メカニズムは、実際にはロックの概念によって制御されます。

マルチスレッドのロック同期メカニズム

ここに画像の説明を挿入
对象锁オブジェクトをロックすると、異なるインスタンスのロックは相互に影響しません。

  1. インスタンスメソッドを同期されたメソッドで修飾する
  2. コードブロックを同期されたもので装飾する

类锁オブジェクトはすべて同じロックを共有し、同期して実行されます。1 つのスレッドの実行が終了した場合にのみ、他のオブジェクト スレッドが同期部分を呼び出すことができます。異なるクラスのロックは相互に影響しません。

  1. 静的メソッドを同期メソッドで修飾する
  2. コードブロックを同期されたもので装飾する

オブジェクト ロックの 2 つの形式: (注synchronized)

public class Test
{
    
    
    // 对象锁:形式1(修饰实例方法)
    public synchronized void Method1()
    {
    
    
        System.out.println("我是对象锁也是方法锁");
        try
        {
    
    
            Thread.sleep(500);
        } catch (InterruptedException e)
        {
    
    
            e.printStackTrace();
        }

    }

    // 对象锁:形式2(修饰代码块)
    public void Method2()
    {
    
    
        synchronized (this)
        {
    
    
            System.out.println("我是对象锁");
            try
            {
    
    
                Thread.sleep(500);
            } catch (InterruptedException e)
            {
    
    
                e.printStackTrace();
            }
        }

    }

クラスロック:

ここに画像の説明を挿入

public class Test
{
    
    
   // 类锁:形式1
    public static synchronized void Method1()
    {
    
    
        System.out.println("我是类锁一号");
        try
        {
    
    
            Thread.sleep(500);
        } catch (InterruptedException e)
        {
    
    
            e.printStackTrace();
        }

    }

    // 类锁:形式2
    public void Method()
    {
    
    
        synchronized (Test.class)
        {
    
    
            System.out.println("我是类锁二号");
            try
            {
    
    
                Thread.sleep(500);
            } catch (InterruptedException e)
            {
    
    
                e.printStackTrace();
            }

        }

    }

Java は監視機構を使用します。
各オブジェクトには 1 つのオブジェクトのみが存在し、スレッド間の排他は锁旗标マルチスレッドのペアの競合によって実現されます。スレッド A がオブジェクトのロック フラグを取得すると、スレッド B はスレッド A を待つ必要があります。指定された操作を完了して解放します。 ロックフラグがロックされた後、オブジェクトのロックフラグを取得し、スレッド B での操作を実行できます。锁旗标

相互に排他的である必要があるステートメントセグメントをsynchronized(object){}ステートメントに挿入し、2 つの場所のオブジェクトが同じであるようにします。

スレッド間の通信

ここに画像の説明を挿入
異なるスレッドの作業をより効果的に調整するには、スレッド間の通信チャネルを確立し、スレッド間の「対話」を通じてスレッド間の同期問題を解決する必要があります。このクラスのいくつかのメソッドは、スレッド間の通信に効果的な手段を提供します。現在の状態が適切
java.lang.Object でない場合
wait() 、このスレッドが実行され、同期コード ( ) を実行しているスレッド A がsynchronizedこのメソッドを (オブジェクト x 上で) 呼び出し、スレッドは実行を一時停止してオブジェクト x の待機プールに入り、オブジェクト x のロック フラグを解放します。取得されたオブジェクト x 。スレッド A は、オブジェクト xのロック フラグを取り戻して実行を続行する前に、notify他のスレッドがオブジェクト x のメソッドを呼び出すまで待機する必要があります (wait ステートメントの後に実行を続行)。notifyAll

notify() 待機中のスレッドをランダムにウェイクアップし、
スレッドは実行を継続します。スレッドがウェイクアップした後、ウェイクアップ メッセージを送信した人がモニターを解放するまで待機する必要があります。この期間中に、キー データが変更される可能性があります。
ウェイクアップしたスレッドが実行を開始するとき、現在の状態が適切であるかどうかを判断する必要があります。自分で実行して
notifyAll() 待機中のスレッドをすべてウェイクアップすると、このスレッドは実行を継続します。

wait、notify/notifyAllの詳細説明

ここに画像の説明を挿入
ここに画像の説明を挿入
マルチスレッドで特定の条件の変化をテストするには、if または while? を使用します。

ここに画像の説明を挿入
明らかに、現在の値が必要な値を満たしている場合にのみスレッドを実行できるため、while ループを使用してブロックする必要がありますここで if を使用すると、ifがwait()継続して下降し、if ステートメント ブロックから飛び出すことを意味します。ただし、notifyAll スレッドを起こすだけであり、条件を保証するものではないため、プログラムのロジックを手動で保証する必要があります。

スレッドのデッドロック

ブロッキング: スレッドの実行を一時停止して、条件が発生するのを待ちます。
IO ブロック:

DatagramSocket.recive(); ServerSocket.recive()

スレッドのブロック

synchronized(obj)等待obj解锁;
wait(),等待其他线程的notify()

重要なリソース
マルチプログラムされたシステムでは、さまざまなリソースを共有するプロセスが多数ありますが、一度に 1 つのプロセスのみが使用できるリソースも多数あります。一度に 1 つのプロセスのみが使用できるリソースは、クリティカル リソースと呼ばれます。入力マシン、プリンター、テープ ドライブなど、多くの物理デバイスは重要なリソースです。
各プロセスは相互に排他的な方式を採用しており、共有されるリソースをクリティカルリソースと呼びます。
重要なリソースに属するハードウェアにはプリンタ、テープ ドライブなどが含まれ、ソフトウェアにはメッセージ バッファ キュー、変数、配列、バッファなどが含まれます。
クリティカルなリソースにアクセスする各プロセスのコード セクションは、
クリティカル セクション
と呼ばれます。明らかに、すべてのプロセスがそれぞれのクリティカル セクションに排他的に入ることが保証できれば、すべてのプロセスによるクリティカル リソースへの相互排他的アクセスが実現できます。

デッドロック
複数のスレッドが同時にブロックされ、そのうちの 1 つまたはすべてがリソースが解放されるのを待っています。スレッドは無期限にブロックされるため、プログラムを正常に終了することはできません。

必要な4つの条件:

互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
循环等待,即存在一个等待队列:
		P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。

一例:
ここに画像の説明を挿入

デッドロックを回避する

sychronized
セマフォ セマフォは
カウント セマフォです。概念的には、セマフォは一連の権限を維持します。必要に応じて、許可が得られるまでそれぞれがブロックしacquire()、その後その許可を取得します。それぞれがrelease()許可を追加し、ブロックしている取得者を解放する可能性があります。ただし、実際のライセンス オブジェクトは使用されず、
Semaphore使用可能なライセンスの数のみがカウントされ、それに応じて処理されます。セマフォを取得したスレッドはコードを入力できますが、それ以外の場合は待機します。アクセス許可を渡しacquire()release()取得および解放します。

クリティカルリソース: 特定の瞬間にのみ排他的(相互排他的)に使用でき、複数の人が異なるタイミングで共有できるリソース。
例:

会社の銀行口座は、複数の人からの資金の入出金を会社によって許可されていますが、一度に入出金できるのは 1 人だけです。
携帯電話などの製品は、まず生産者によって生産され、その後消費者に販売されますが、製品の生産と消費を同時に行うことはできません。

スレッドの同期と相互排他: 複数のスレッド間の相互協力 (ステップ調整) を伴う重要なリソースの処理。
synchronized锁定方法、重要なリソースに「ロック」を追加するなど、メソッド実行プロセスが重要なリソース上で「同期」(適切なステップと連携)できるようにします。
synchronized重要なリソースをロックする構文:

synchronized( 临界资源对象 ){
    
     操作代码 } 

生産者・消費者モデル
(1) には、製品を保管するための一定の容量を備えた倉庫があります。
(2) 生産者は製品を生産し続け、製品は倉庫(製品保管庫)に保管されます。
(3) 消費者は倉庫内の製品を購入し続けます(倉庫からの製品)。
(4) 生産者は倉庫に空きがある場合にのみ生産でき、空きがない場合は待つしかありません。
(5) 消費者は、倉庫に商品がある場合にのみ購入(消費)することができます。

产品生産者および消費者モデルには、 、仓库生产者およびの 4 つの概念が関係しており消费者、重要なのは後の 3 つです。

仓库,是临界资源,仓库的产品不能同时入仓和出仓。
生产者线程:工人。
消费者线程:购买产品的人。

現実世界では、企業の銀行口座の入出金業務など、多くの問題は生産者消費者モデルに起因すると考えられます。銀行口座は巨大な倉庫に相当し、生産(入金)には制限がありません。 ) 容量。

ここに画像の説明を挿入

バックグラウンドスレッド

バックグラウンド スレッド (
デーモン スレッドとも呼ばれます) は、通常、他のスレッドを支援するために実行されるスレッドです。プロセス内で実行されているフォアグラウンド スレッドが 1 つある限り、プログラムの終了
を妨げるものではありません
。すべてのフォアグラウンド スレッドが実行されている場合、プロセスは終了しません。プロセス内のスレッドは終了しているため、未完了のバックグラウンド スレッドがあるかどうかに関係なく、このプロセスは終了します。
「ガベージ コレクション」はバックグラウンド スレッドです。スレッド オブジェクトが開始される前にメソッドが呼び出された
場合(start メソッドの呼び出し)、setDaemon(true)メソッド)、スレッドはバックグラウンド スレッドになります

Java には 2 種類のスレッドがありますUser Thread(用户线程):Daemon Thread(守护线程)

ユーザー スレッド: フォアグラウンドで実行されているスレッド (通常のスレッドとも呼ばれます) は、ユーザーが完了したいタスクのみを完了し、パブリック サービスは提供しません。

ここに画像の説明を挿入
無限ループのバックグラウンド スレッドを作成し、メイン スレッドの終了後にプログラムが終了することを確認します。プログラムを
実行し、メイン スレッドの終了時にプログラム全体の実行が停止することを確認します。t.setDaemon(true)ステートメントがコメント アウトされている場合、プログラムは終了しません。
ここに画像の説明を挿入

スレッドの寿命

スレッドのライフサイクルとは、スレッド
が生成されてから消滅するまでの過程であり
、スレッドは常に特定のスレッド状態 (スレッド状態) にあります。

ここに画像の説明を挿入
ここに画像の説明を挿入

スレッドの寿命を制御する

スレッドの寿命を終える

stopスレッドの寿命を終了するには、 の方法を使用します
が、スレッドが共有データセグメントを操作している場合、操作プロセスが完了せずに stop を使用して終了すると、データが不完全になるため、この方法は推奨されません

通常、スレッドは run メソッドでループ条件を制御することで終了できます。

スレッドの優先順位

スレッドのスケジューリング
シングル CPU システムでは、複数のスレッドが CPU を共有する必要があり、実際に実行できるスレッドは常に 1 つだけです

複数のスレッドが同じ CPU 上で特定の順序で実行されるように制御することをスレッド スケジューリングといいます。

Java 仮想マシンは、固定優先順位アルゴリズムと呼ばれる、非常に単純な決定論的なスケジューリング アルゴリズムをサポートしています。このアルゴリズムは、スレッドの優先順位に基づいてスレッドをスケジュールします。

スレッドの優先順位
各 Java スレッドには、次の範囲の優先順位があります1和10デフォルトでは、各スレッドの優先度は 5 に設定されます。
スレッド A の実行中に作成された新しいスレッド オブジェクト B は、初期状態のスレッド A と同じ優先度を持ちます。A が
バックグラウンド スレッドの場合、B もバックグラウンド スレッドになります。
スレッドの作成後はいつでもsetPriority(int priority)メソッドを通じて元の優先順位を変更できます

スレッドの優先順位に基づくスレッドのスケジューリング
優先順位の高いスレッドは、優先順位の低いスレッドよりも先に実行されます
。 同じ優先順位のスレッドの場合、Java の処理はランダムであり、
基礎となるオペレーティング システムがサポートする優先順位が 10 未満の場合があるため、混乱が生じる可能性があります。したがって、優先順位は大まかなツールとしてのみ使用してください。最終的な制御は、yield() 関数を賢明に使用することで実行できますが、
スレッドの優先順位は効率性を考慮してのみ使用でき、アルゴリズムの正確性を保証するためにスレッドの優先順位に依存することはできません。

スレッドが実行中の場合、スレッドは次のいずれかの条件が発生した場合にのみ一時停止されます。

  1. 優先度の高いスレッドが準備完了 (Ready) になります。
  2. 入出力 (またはその他の理由) により、sleep、wait、yield メソッドの呼び出しによりブロックされます。
  3. タイム スライスをサポートするシステムの場合、タイム スライスの時間は期限切れになります。

おすすめ

転載: blog.csdn.net/qq_51594676/article/details/125240334