スレッドセーフ
同時に実行されている複数のスレッドがあり、これらのスレッドがこのコードを同時に実行する可能性がある場合、各プログラムの実行結果は単一のスレッド実行の結果と同じであり、他の変数の値は期待どおりです、つまりスレッドセーフ。つまり、複数のスレッドが特定のクラス(オブジェクト)にアクセスする場合、このクラスは常に正しい動作を示すことができます。
チケット販売のケースは、スレッドセーフティの問題をシミュレートします。
[ケースの説明]映画館がチケットを販売したい場合、映画館のチケット販売プロセスをシミュレートします。上映する映画が「ウルフウォリアー3」であるとすると、この映画の座席数は100になります(この映画では100チケットしか販売できません)。映画館のチケットウィンドウをシミュレートして、複数のウィンドウが「Calabash Baby vs. Ultraman」のチケットを同時に販売できることを理解しましょう(複数のウィンドウがこれらの100チケットを一緒に販売します)ウィンドウが必要であり、スレッドオブジェクトがシミュレーションに使用されます。チケットが必要で、実行可能ですシミュレートするインターフェイスサブクラス。
プログラムのデモ:
public class RunnableImpl implements Runnable{
//定义一个多线程共享的票源
private int ticket = 100;
//设置线程任务:卖票
@Override
public void run() {
while (true) {
//先判断票是否存在
if(ticket > 0) {
//票存在,卖票 ticket--
//提高安全问题出现的概率,让程序睡眠
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ "-->正在,卖第"+ ticket + "张票");
ticket--;
}
}
}
}
/*
模拟卖票案例
创建3个线程,同时开启,对共享的票进行出售
*/
public class Demo01Ticket {
public static void main(String[] args) {
//创建Runnable接口的实现类对象
Runnable run = new RunnableImpl();//多态
//创建Thread类对象,构造方法中传递Runnable接口的实现类对象
Thread t0 = new Thread(run);
Thread t1 = new Thread(run);
Thread t2 = new Thread(run);
//调用start方法开启多线程
t0.start();
t1.start();
t2.start();
}
}
プログラムに2つの問題があることがわかります。
- 同じ票数、たとえば、7番目のチケットは2回販売されました。
- 0票や-1票など、存在しない票は存在しません。
この種の問題、いくつかのウィンドウ(スレッド)の投票数は同期されていません。これはスレッドの不安定性と呼ばれます。
スレッドセーフティの問題は、グローバル変数と静的変数が原因で発生します。各スレッドにグローバル変数と静的変数の読み取り操作のみがあり、書き込み操作がない場合、一般的に言えば、このグローバル変数はスレッドセーフです。複数のスレッドが同時に書き込み操作を実行する場合、スレッド同期を考慮する必要があります。それ以外の場合スレッドの安全性に影響を与える可能性があります。