背景ノート:
後に、好奇心から、私は終わりでJavaを知りたいと思ったが、マルチスレッド化されていないマルチスレッドのJava(継承されたスレッド、Runnableを)の研究では、彼が、マルチスレッド、マルチスレッドされていることを言うことができない、彼らはテストしたいので、私はしたかったですテストが、(個人的な感情は、javaファイルをプロジェクトレベルに上昇しなかったスクリプトです)マルチスレッド生成しないにつながるため、継承のJavaの単一のフォームにスレッドを継承しますが、Runnableを、できるので、私は、スクリプトを作った、私も生成チケットシステムをシミュレートする10件のスレッドは、10枚のチケットを購入する人をシミュレートするスレッドを想定し、人はチケットの時間を買う(ない、同時に2つのチケットなどを購入する)0.5秒で、その100を観察どのくらいの時間、チケットの購入を完了します。
問題は、1に遭遇しました:
問題の説明:
まず、どのくらいの時間シェアを計算することで、以下に示すように、私が書くために、コードのフレームワークを利用した、問題を発見した:現在のJavaメインプログラムはスレッド、実行時にメインのJavaプログラムですので、あなたはこれらの10個のスレッドを作成した後、メインのJavaプログラムの実行が完了すると、それはこの10個のスレッドを実行するかどうかを制御しないであろう時間は問題がある、計算されたときに、完了です。合計時間が出力されます(出力時間は、スレッドを実行していない)スレッドを実行しています
ステップ1の解決:
ソリューションのフィギュア、説明:私はendTimeは、スレッドの静的インタフェースの実装クラスで変数を共有し、10件のスレッドが成功を作成して実行するには、この時間は、最後のスレッドの実行が終わりの時であるとき、最後に変更された定義10件のスレッドは、時間が計算され、最終的に時間を完了するために実行されています。問題は、javaはまだメインスレッド、出力誤差の時間ですので、まだ統計的な時間が解決しない、来ます。
ステップ2を解きます:
メインプログラムはJavaのスレッドが考慮されながら、私は推定睡眠時間は、スレッドの計算時間よりもわずかに大きい、(事前に予測時間と睡眠時間を設定)スリープ今javaのメインスレッド10個のスレッドを作成しました
最後に:
問題を解決するための時間が、今回は10件のスレッドが同じデータにアクセスし、変更する場合と、データが故障している可能性があり、大きな問題につながりました。今回はデータのための相互排他メカニズムをスレッドする必要があります。
コード:
メインプログラムのJavaコード:javaThreadTest
package org.axc.com.javathread;
import java.util.Scanner;
/**
*
* @ClassName: javaThreadTest
* @Description: 测试java线程的运行
* @author Anxc
* @date 2019年8月8日
*
*/
public class JavaThreadTest {
public static void main(String[] args) {
// 线程的创建
MyThread mythread;
System.out.println("---------继承Thread方式来实现创建线程-----------------");
Scanner in = new Scanner(System.in);
String menu="线程测试开始";
int chioce=1;
while(chioce!=0) {
mythread = new MyThread();
System.out.println("请输入非0来开始调试继承的Thread");
System.out.print(">>");
chioce = in.nextInt();
if(chioce==0) {
System.out.println("ByeBye");
break;
}
// 输出菜单
System.out.println(menu);
// 线程运行
mythread.start();
}
System.out.println("------------利用Runnable接口实现创建线程-------------");
// 测试Runnable的多线程所用时间
chioce = 1;
// 利用Runnable接口,初始化线程
Runnable runnable = new MyRunnable();
long startTime;
long endTime;
while(chioce!=0) {
System.out.println("请输入非0来开始调试");
System.out.print(">>");
chioce = in.nextInt();
if(chioce == 0) {
System.out.println("Runnable ByeBye!");
break;
}
startTime = System.currentTimeMillis();
System.out.println(startTime);
// 创建10个线程来观察是否是真的多线程运行
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
Thread t=new Thread(runnable);
//t.isAlive();//判断线程是否存活
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 输出最后所用时间
System.out.println("最终所用时间为:"+(((MyRunnable) runnable).getEndTime()-startTime));
}
}
}
Runnableインタフェースを実装するJavaプログラムコード:MyRunnable
package org.axc.com.javathread;
/**
*
* @ClassName: MyRunnable
* @Description: 测试Runnable的真正多线程
* @author Anxc
* @date 2019年8月8日
*
*/
public class MyRunnable implements Runnable {
private static int count=100; //加互斥锁,当一个线程去修改值时,其它线程不能读取
public static long endTime;
private static boolean flag=true;
public MyRunnable() {
}
@Override
public void run() {
int num=10;
// 加锁,使修改变量时只有一个线程在操作
while(num>0) {
if(flag) {
flag=false;//加锁
count--;
// TODO Auto-generated method stub
System.out.println("当前剩余"+count);
flag=true;//关锁
}
else {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
continue;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
num--;
}
// 获取线程运行终止时间
endTime = System.currentTimeMillis();
// System.out.println(endTime);
}
public long getEndTime() {
return endTime;
}
}
继承Thread的方法的java程序:MyThread
package org.axc.com.javathread;
/**
*
* @ClassName: MyThread
* @Description: java线程的实现方式之一继承Thread
* @author Anxc
* @date 2019年8月8日
*
*/
public class MyThread extends Thread {
private static int count = 0;
public void run() {
int num=0;
count++;
while(num<5) {
System.out.println("再等等!"+count+num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
num++;
}
System.out.println("当前已经累计运行该线程:"+count+"次");
}
}