2021.2.19
- Javaの基本(簡単な答え)------マルチスレッド(同期メソッドの装飾?stop()メソッドとsuspend()メソッドが推奨されないのはなぜですか?)
- Javaの基本(簡単な答え)------マルチスレッド(sleep()とwait()の違いは何ですか?)
- Javaの基本(簡単な回答)------マルチスレッド(同期とjava.util.concurrent.locks.Lockの類似点と相違点を簡単に説明しますか?)
- Javaの基本(演習)------マルチスレッド(銀行引き出しの問題のシミュレーション)
- Java(Dug)------日食マウスはクロスソリューションになります
- Javaの基本(演習)------マルチスレッド(カメとウサギの問題)
- Javaの基本(演習)------マルチスレッド(同期モニターの選択)
- Javaの基本(演習)------マルチスレッド(notify()、wait()メソッドは、スレッドが継続的に印刷できないようにすることができます)
Javaの基本(簡単な答え)------マルチスレッド(同期メソッドの装飾?stop()メソッドとsuspend()メソッドが推奨されないのはなぜですか?)
- 安全ではないため、stop()。スレッドによって取得されたすべてのロックを解放し、オブジェクトがインコヒーレント状態にある場合、他のスレッドはその状態でそれらをチェックおよび変更できます。その結果、実際の問題を検出することは困難です。
- suspend()メソッドはデッドロックを起こしやすいです。suspend()が呼び出されると、ターゲットスレッドは停止しますが、それ以前に取得したロックは保持されます。このとき、「中断された」スレッドが操作を再開しない限り、他のスレッドはロックされたリソースにアクセスできません。どのスレッドでも、ロックされたリソースを同時に使用しようとしているときにターゲットスレッドを復元したい場合は、デッドロックが発生します。したがって、suspend()は使用しないでください。ただし、スレッドをアクティブにするか中断するかを示すフラグをThreadクラスに配置する必要があります。フラグがスレッドを一時停止する必要があることを示している場合は、wait()を使用して、スレッドを待機状態にするように命令します。フラグがスレッドを再開する必要があることを示している場合、notify()を使用してスレッドを再開します。
Javaの基本(簡単な答え)------マルチスレッド(sleep()とwait()の違いは何ですか?)
- スリープはスレッドクラス(Thread)のメソッドであり、このスレッドが指定された時間実行を一時停止し、他のスレッドに実行の機会を与えますが、監視状態は維持され、その後自動的に再開されます。sleepを呼び出しても、オブジェクトロックは解放されません。
- WaitはObjectクラスのメソッドです。このオブジェクトでwaitメソッドを呼び出すと、スレッドはオブジェクトロックを放棄し、このオブジェクトを待機している待機ロックプールに入ります。このオブジェクトに対してnotifyメソッド(またはnotifyAll)が発行された後でのみ、スレッドはオブジェクトロックプールに入り、それを取得する準備をします。オブジェクトロックは実行状態になります。
Javaの基本(簡単な回答)------マルチスレッド(同期とjava.util.concurrent.locks.Lockの類似点と相違点を簡単に説明しますか?)
- 主な類似点:ロックは、同期によって実現されるすべての機能を完了できます
- 主な違い:ロックは、同期よりも正確なスレッドセマンティクスと優れたパフォーマンスを備えています。同期すると自動的にロックが解除されます、そしてロックはプログラマーが手動で解放する必要があり、finally節で解放する必要があります。
Javaの基本(演習)------マルチスレッド(銀行引き出しの問題のシミュレーション)
アカウントクラス
public class Account {
private String idString;
private double balance;
public Account() {
super();
}
public Account(String idString, double balance) {
super();
this.idString = idString;
this.balance = balance;
}
public String getIdString() {
return idString;
}
public void setIdString(String idString) {
this.idString = idString;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((idString == null) ? 0 : idString.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Account other = (Account) obj;
if (idString == null) {
if (other.idString != null)
return false;
} else if (!idString.equals(other.idString))
return false;
return true;
}
@Override
public String toString() {
return "Account [idString=" + idString + ", balance=" + balance + "]";
}
}
テストクラス
Java(Dug)------日食マウスはクロスソリューションになります
- ショートカットキーを使用する:alt + shift + a
Javaの基本(演習)------マルチスレッド(カメとウサギの問題)
/*
* 编写龟兔赛跑多线程程序,设赛跑长度为100米,每跑完10米输出一次结果。
改进上题的龟兔赛跑程序,通过改变优先级,
并减掉休眠时间,使得乌龟以迅雷不及掩耳的速度跑完100米。
*/
public class Demo5 {
public static void main(String[] args) {
TortoiseRun tesTortoiseRun = new TortoiseRun();
RabbitRun testRabbitRun = new RabbitRun();
Thread t1 = new Thread(tesTortoiseRun);
Thread t2 = new Thread(testRabbitRun);
t1.setName("乌龟");
t2.setName("兔子");
t1.start();
t2.start();
}
}
//乌龟跑100米
class TortoiseRun implements Runnable{
int journey = 100;
@Override
public void run() {
synchronized (this) {
for(int i = 0;i <= 100;i++) {
try {
Thread.sleep(20);
}catch(InterruptedException e) {
e.printStackTrace();
}
if(i==10 || i==20||i==30 || i==40||i==50 || i==60||i==70 || i==80||i==90 || i==100) {
System.out.println(Thread.currentThread().getName() +"跑了" + i + "米");
}
}
}
}
}
class RabbitRun implements Runnable{
int journey = 100;
@Override
public void run() {
synchronized (this) {
for(int i = 0;i <= 100;i++) {
try {
Thread.sleep(50);
}catch(InterruptedException e) {
e.printStackTrace();
}
if(i==10 || i==20||i==30 || i==40||i==50 || i==60||i==70 || i==80||i==90 || i==100) {
System.out.println(Thread.currentThread().getName() +"跑了" + i + "米");
}
}
}
}
}
試験結果
Javaの基本(演習)------マルチスレッド(同期モニターの選択)
/*
* 启动两个线程对一个数字i操作
*1)其中1个线程每次对i加1
*2)另1个线程每次对i减1
*各运行20次,结果i的值等于初始值。
*/
public class Demo6 {
public static void main(String[] args) {
number num = new number(20);
Add add = new Add(num);
Sub sub = new Sub(num);
Thread t1 = new Thread(add);
Thread t2 = new Thread(sub);
t1.setName("+1操作:");
t2.setName("-1操作:");
t1.start();
t2.start();
// try {
// t1.join(15);
// }catch (InterruptedException e) {
// e.printStackTrace();
// }
// try {
// t2.join(14);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
class number{
private static int i;
public number(int i) {
this.i = i;
}
public int getI() {
return i;
}
public void setI() {
this.i =i;
}
public void sub() {
i--;
}
public void add() {
i++;
}
}
class Add implements Runnable{
private number num;
public Add(number num) {
this.num = num;
}
public void run() {
synchronized (num) {
for(int j = 0; j < 20; j++){
try {
Thread.sleep(20);
}catch(InterruptedException e) {
e.printStackTrace();
}
num.add();
System.out.println(Thread.currentThread().getName() + "对i+1后,i 的值为:" + num.getI());
}
}
}
}
class Sub implements Runnable{
private number num;
public Sub(number num) {
this.num = num;
}
@Override
public void run() {
synchronized (num) {
for(int j = 0; j < 20; j++){
try {
Thread.sleep(20);
}catch(InterruptedException e) {
e.printStackTrace();
}
num.sub();
System.out.println(Thread.currentThread().getName() + "对i-1后,i 的值为:" + num.getI());
}
}
}
}
ここでは、番号iを属性として別のNumberクラスにカプセル化し、Numberクラスのオブジェクトを同期モニターとして使用して、複数のスレッドが同期モニターを共有できるようにする必要があります。
Javaの基本(演習)------マルチスレッド(notify()、wait()メソッドは、スレッドが継続的に印刷できないようにすることができます)
/*
* 实现一个由A、B、C三个窗口同时销售100张票的系统,
* 要求打印出每个窗口打印的售票情况,并且每个窗口不得连续售票
*/
public class Demo7 {
public static void main(String[] args) {
windows testWindows = new windows();
Thread t1 = new Thread(testWindows);
Thread t2 = new Thread(testWindows);
Thread t3 = new Thread(testWindows);
t1.setName("窗口一");
t2.setName("窗口二");
t3.setName("窗口三");
t1.start();
t2.start();
t3.start();
}
}
class windows implements Runnable{
private static int titck = 1;
@Override
public void run() {
while(titck < 99) {
synchronized (this) {
this.notify();
try {
Thread.sleep(10);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "票号为:" + titck);
titck++;
try {
this.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}