Java の知識ポイントの要約: マルチスレッドの基本
この記事では、java に関する関連知識を提供し、主にマルチスレッドに関する関連内容を紹介します。複数のスレッドを同時に実行できます。例: Thunder を使用して複数のファイルを同時にダウンロードできます。見てみましょう。皆さんのお役に立てれば幸いです。
Java ビデオ チュートリアル #」
#1. スレッド関連の概念
1、プログラム: 特定のタスクを完了するために特定の言語で書かれた一連の命令です。簡単に言うと、 は私たちが書いたコード です。
プロセス: 実行中のプログラムを指します。たとえば、QQ を使用する場合、プロセスを開始すると、オペレーティング システムがプロセスにメモリ領域を割り当てます。 Thunder を使用して別のプロセスを開始すると、オペレーティング システムは Thunder に新しいメモリ領域を割り当てます。
プロセスとは、プログラムの実行、または実行中のプログラムです。それは動的なプロセスであり、出現、存在、消滅という独自のプロセスがあります。 3,スレッド: プロセスによって作成され、プロセスのエンティティです。プロセスには複数のスレッドを持つことができます。たとえば、Thunder を使用してダウンロードします。ファイル、Thunder は process に相当し、ダウンロードされたファイルはスレッドに相当します。
シングルスレッド: 同時に、 は 1 つのスレッド のみを実行できます。
マルチスレッド: は同時に複数のスレッドを実行できます。たとえば、Thunder を使用すると、複数のファイルを同時にダウンロードできます。
同時実行性: 同時に、複数のタスクが交互に実行されます。シングルコア CPU によって実現されるマルチタスクは同時実行です。
Parallel: 同時に、複数のタスクが同時に実行されます。マルチコア CPU は並列処理を実現できますが、タスクが多い場合には、同時実行と並列処理が同時に発生する可能性があります。
2. スレッドの基本的な使用方法
スレッドを作成するには 2 つの方法があります: 1.Thread を継承します。クラスを作成し、
runMethod をオーバーライドします。
Runnable インターフェイスを実装し、
run メソッドをオーバーライドします。
Thread クラスは、
Runnable インターフェイスを実装します。
(1) Thread クラスを継承し、run メソッド public class Thread01 {
public static void main(String[] args) throws InterruptedException {
Cat cat = new Cat();
cat.start();
System.out.println("主线程" + Thread.currentThread().getName());
for (int i = 1; i
ログイン後にコピー
1 をオーバーライドします。public class Thread01 { public static void main(String[] args) throws InterruptedException { Cat cat = new Cat(); cat.start(); System.out.println("主线程" + Thread.currentThread().getName()); for (int i = 1; i
Thread クラスを継承し、
run をオーバーライドします。 method ()メソッドの後に、
main メソッドでオブジェクトを作成し、
start() メソッドを呼び出してスレッドを開始する必要があります。
start() メソッドを使用すると、書き換えられた
run() メソッドが呼び出されます。
main メソッドの場合、
start() メソッドの後に実行ステートメントがあり、
run( ) メソッド ,
main スレッド内でサブスレッド
Thread-0 が開始されます。メイン スレッドはブロックされず、メイン スレッドとサブスレッドが実行されます交互に。
run()# を直接呼び出すのではなく、メインスレッドで start()
メソッドを使用して run()
メソッドを呼び出す理由## メソッド。run()
メソッドは通常のメソッドであり、実際にはスレッドを開始しません。run()
メソッドが呼び出されると、run()
メソッドが実行されます。完了後、main
メソッドの残りのステートメントが実行されると、メイン スレッドがブロックされます。 したがって、上記のプログラムの結果は次のようになります:
主线程main 主线程i=1你好1Thread-0主线程i=2你好2Thread-0主线程i=3你好3Thread-0主线程i=4你好4Thread-0主线程i=5你好5Thread-0
(2) Runnable インターフェイスを実装し、run メソッドをオーバーライドしますpublic class Thread02 {
public static void main(String[] args) {
Dog dog = new Dog();
Thread thread = new Thread(dog);
thread.start();
}}class Dog implements Runnable{
@Override public void run() {
int count = 0;
while (true) {
System.out.println("小狗汪汪叫" + (++count) + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 10){
break;
}
}
}}
ログイン後にコピー1。
Runnablepublic class Thread02 { public static void main(String[] args) { Dog dog = new Dog(); Thread thread = new Thread(dog); thread.start(); }}class Dog implements Runnable{ @Override public void run() { int count = 0; while (true) { System.out.println("小狗汪汪叫" + (++count) + Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (count == 10){ break; } } }}
インターフェイスには start()
メソッドがないため、agent
が必要です。 2. まず、main メソッドでオブジェクトを作成し、次に
オブジェクトを作成し、前に作成したオブジェクト を Thread
に渡し、Thread を使用して # を呼び出します。 # #start()スレッドを作成するメソッド。
3. Runnable インターフェイスの実装は、複数のスレッドがリソースを共有するのに適しており、単一継承の制限を回避できるため、
Runnable
(1) 基本的な手順
1. スレッドがタスクを完了すると、自動的に終了します。
2.変数を使用してrun()
メソッドを制御し、終了スレッドを終了することもできます。1. スレッド内の run()
メソッドが内部的にwhile(true){ }、つまり
無限ループ。
2. スレッド内に
boolean 属性loop
while(loop){}を実行できます。
3. 別の
setLoop
public class ThreadExit {
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.start();
Thread.sleep(10000);
t.setLoop(false);
}}class T extends Thread{
private boolean loop = true;
private int times = 0;
@Override public void run() {
while (loop){
System.out.println("hello" + (++times));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void setLoop(boolean loop) {
this.loop = loop;
}}
ログイン後にコピー
4. 共通スレッド メソッドpublic class ThreadExit { public static void main(String[] args) throws InterruptedException { T t = new T(); t.start(); Thread.sleep(10000); t.setLoop(false); }}class T extends Thread{ private boolean loop = true; private int times = 0; @Override public void run() { while (loop){ System.out.println("hello" + (++times)); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } public void setLoop(boolean loop) { this.loop = loop; }}
(1)最初のグループ
1、setName
: スレッド名をパラメータ名と同じに設定します。2、getName:返回该线程名称。
3、start:使该线程开始执行,JAVA虚拟机底层调用该线程的start0方法。
4、run:调用线程对象的run方法。
5、setPriority:更改线程的优先级。
6、getPriority:获取线程的优先级。
7、sleep:在指定的毫秒数内,让当前正在执行的线程休眠。
8、interrupt:中断线程。
注意事项:
1、start()
底层会创建新的线程,调用run(),run()
就是一个简单的方法调用,不会启动新线程
。
2、中断线程一般用于中断正在休眠的线程
,并没有真正的结束线程,所以如果线程中每输出内容后,会调用Thread.sleep()
进行休眠的话,我们可以调用interrupt()
方法将其提前唤醒
。
代码演示:
public class ThreadMethod01 { public static void main(String[] args) throws InterruptedException { T t = new T(); t.setName("邱崇源"); t.setPriority(1); t.start(); for (int i = 0; i <h4> <a id="_183"></a>(二)第二组</h4><p>1、<strong>yield</strong>:是一个<code>静态方法</code>,表示<code>线程的礼让</code>。让出<code>CPU</code>,让其他线程执行,但是<code>不一定成功</code>,因为这取决于CPU,如果CPU认为两个线程可以一起执行,则不进行礼让,所以<code>如果CPU的核数多,并且线程数少,礼让就会大概率失败</code>。</p><p>2、<strong>join</strong>:表示<code>线程的插队</code>,假如主线程与子线程正在交替运行,我们想<code>先让子线程执行</code>完毕,然后再让主线程执行,就可以使用线程插队,在主线程中,创建子线程对象,并调用<code>join</code>方法,可以实现线程插队,线程插队<code>一定会成功</code>,先<code>执行完插入线程任务后,再继续执行主线程</code>。</p><h4> <a id="_186"></a>代码演示:</h4><pre class="brush:php;toolbar:false">public class ThreadMethod02 { public static void main(String[] args) throws InterruptedException { A a = new A(); a.start(); for (int i = 1; i <h2> <a id="_219"></a>五、用户线程和守护线程</h2><p>1、<strong>用户线程</strong>:也叫<code>工作线程</code>,线程的任务执行完或通知方式结束。</p><p>2、<strong>守护线程</strong>:一般是<code>为工作线程服务</code>的,当<code>所有的用户线程结束</code>,<code>守护线程自动结束</code>。</p><h4> <a id="_222"></a>应用场景:</h4><p>如果有两个线程,主线程运行结束,但子线程是无限循环。我们想让主线程结束的同时,子线程也结束,就需要让子线程变成守护线程。</p><p>在主线程中,创建子线程对象,并调用<code>setDaemon(true)</code>,让子线程变成守护线程。</p><p>注意:一定要放在<code>start方法之前</code>。</p><h4> <a id="_226"></a>代码演示:</h4><pre class="brush:php;toolbar:false">public class ThreadMethod03 { public static void main(String[] args) throws InterruptedException { MyDaemonThread myDaemonThread = new MyDaemonThread(); myDaemonThread.setDaemon(true); myDaemonThread.start(); for (int i = 1; i <h2> <a id="_254"></a>六、线程的生命周期</h2><h4> <a id="1JDK__ThreadState__255"></a>1、JDK 中用 Thread.State 枚举表示了线程的几种状态</h4><p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/067/2235493b090cc60a6a3c1434c8852f59-0.png" class="lazy" alt="Java の知識ポイントの要約: マルチスレッドの基本"></p><h4> <a id="2_257"></a>2、线程状态转换图</h4><p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/067/cfbba58b413c41b084c9e0cab6295dfe-1.png" class="lazy" alt="Java の知識ポイントの要約: マルチスレッドの基本"></p><h2> <a id="_259"></a>七、线程的同步</h2><h4> <a id="1_260"></a>1、应用场景:</h4><p>假如有100张票,有三个线程同时进入该方法买票,票就有可能超卖。所以我们需要线程同步机制,保证数据在同一时刻,最多有一个线程访问。</p><p>可以采取同步方法,在方法中加入<code>synchronized</code>关键字。</p><p>也可以采用同步代码块,<code>synchronized(对象){}</code>。</p><p>注意:<code>synchronized是非公平锁</code>,如果这次第一个线程访问了数据,那么下一次第一个线程也有可能访问到数据。</p><p>如果同步方法是<code>非静态</code>的,那么锁可以是this,也可以是其他对象,但要求是同一个对象。</p><p>例:<code>synchronized(this)</code>。</p><p>如果同步方法是<code>静态</code>的,锁为当前类本身。</p><p>例:<code>synchronized(类名:class)</code>。</p><h4> <a id="2_270"></a>2、代码演示:</h4><pre class="brush:php;toolbar:false">public class SellTicket { public static void main(String[] args) { SellTicket02 sellTicket04 = new SellTicket02(); Thread thread1 = new Thread(sellTicket04); Thread thread2 = new Thread(sellTicket04); Thread thread3 = new Thread(sellTicket04); thread1.start(); thread2.start(); thread3.start(); }}class SellTicket02 implements Runnable { public static int ticket = 100; private boolean loop = true; public synchronized void sell() { if (ticket <h2> <a id="_309"></a>八、线程的死锁</h2><h4> <a id="1_310"></a>1、基本介绍</h4><p>多个线程都占用了对方的锁资源,但不肯相让,就导致了死锁,在编程中,一定要避免死锁的发生。</p><h4> <a id="2_312"></a>2、发生场景:</h4><p>例如:A和B的面前都各有两道门,A的第一道门是o1,第二道门是o2。B的第一道门是o2,第二道门是o1。他们的面前有两把锁,一个是o1锁,一个是o2锁,假如A抢到了o1锁,B抢到了o2锁,但是他们只可打开各自的第一道门,第二道门都没有打开,那么他们都无法释放自己的锁资源,又不可能相让,因此发生了死锁。</p><h4> <a id="3_314"></a>3、代码演示:</h4><pre class="brush:php;toolbar:false">public class DeadLock_ { public static void main(String[] args) { //模拟死锁现象 DeadLockDemo A = new DeadLockDemo(true); A.setName("A 线程"); DeadLockDemo B = new DeadLockDemo(false); B.setName("B 线程"); A.start(); B.start(); } }class DeadLockDemo extends Thread { static Object o1 = new Object();// 保证多线程,共享一个对象,这里使用 static static Object o2 = new Object(); boolean flag; public DeadLockDemo(boolean flag) {//构造器 this.flag = flag; } @Override public void run() { if (flag) { synchronized (o1) { System.out.println(Thread.currentThread().getName() + " 进入 1"); synchronized (o2) { System.out.println(Thread.currentThread().getName() + " 进入 2"); } } } else { synchronized (o2) { System.out.println(Thread.currentThread().getName() + " 进入 3"); synchronized (o1) { System.out.println(Thread.currentThread().getName() + " 进入 4"); } } } } }
九、释放锁
1、下面操作会释放锁
当前线程的同步方法,同步代码块执行结束。
当前线程在同步代码块,同步方法中遇到break,return
。
当前线程在同步代码块,同步方法中出现了未处理的错误或异常
,导致异常结束。
当前线程在同步代码块,同步方法中执行的线程对象的wait方法
,当前线程暂停,并释放锁。
2、 下面操作不会释放锁
线程执行同步代码块和同步方法时,程序调用
Thread.sleep(),Thread.yield()
方法暂停当前线程的执行,不会释放锁。
线程执行同步代码块时,其他线程调用了该线程的suspend()
方法将该线程挂起,该线程不会释放锁。
推荐学习:《java视频教程》
以上がJava の知識ポイントの要約: マルチスレッドの基本の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです
