- 生成一個長度是3的隨機字符串,把這個字符串當作 密碼
- 創建一個破解線程,使用窮舉法,匹配這個密碼
- 創建一個日誌線程,打印都用過哪些字符串去匹配,這個日誌線程設計爲守護線程
提示: 破解線程把窮舉法生成的可能密碼放在一個容器中,日誌線程不斷的從這個容器中拿出可能密碼,並打印出來。 如果發現容器是空的,就休息1秒,如果發現不是空的,就不停的取出,並打印。
解題代碼:
窮舉密碼的線程
package multiplethread;
import java.util.List;
public class PasswordThread extends Thread{
private boolean found = false;
private String password;
private List<String> passwords;
public PasswordThread(String password, List<String> passwords) {
this.password = password;
this.passwords = passwords;
}
public void run(){
char[] guessPassword = new char[password.length()];
generatePassword(guessPassword, password);
}
public void generatePassword(char[] guessPassword, String password) {
generatePassword(guessPassword, 0, password);
}
public void generatePassword(char[] guessPassword, int index, String password) {
if (found)
return;
for (short i = '0'; i <= 'z'; i++) {
char c = (char) i;
if (!Character.isLetterOrDigit(c))
continue;
guessPassword[index] = c;
if (index != guessPassword.length - 1) {
generatePassword(guessPassword, index + 1, password);
} else {
String guess = new String(guessPassword);
//窮舉每次生成的密碼,都放進集合中
passwords.add(guess);
if (guess.equals(password)) {
System.out.println("找到了,密碼是" + guess);
found = true;
return;
}
}
}
}
}
記錄日誌的守護線程
package multiplethread;
import java.util.List;
public class LogThread extends Thread{
private boolean found = false;
private List<String> passwords;
public LogThread(List<String> passwords) {
this.passwords = passwords;
this.setDaemon(true);//把記日誌的這個線程,設置爲守護線程
}
public void run(){
while(true){
while(passwords.isEmpty()){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String password = passwords.remove(0);
System.out.println("窮舉法本次生成的密碼是:" +password);
}
}
}
測試類
package multiplethread;
import java.util.ArrayList;
import java.util.List;
public class TestThread {
public static boolean found = false;
public static void main(String[] args) {
String password = randomString(3);
System.out.println("密碼是:" + password);
List<String> passwords = new ArrayList<>();
//啓動猜測密碼進程
new PasswordThread(password,passwords).start();
//啓動輸出密碼日誌進程
new LogThread(passwords).start();
}
//隨機生成密碼
private static String randomString(int length) {
String pool = "";
for (short i = '0'; i <= '9'; i++) {
pool += (char) i;
}
for (short i = 'a'; i <= 'z'; i++) {
pool += (char) i;
}
for (short i = 'A'; i <= 'Z'; i++) {
pool += (char) i;
}
char cs[] = new char[length];
for (int i = 0; i < cs.length; i++) {
int index = (int) (Math.random() * pool.length());
cs[i] = pool.charAt(index);
}
String result = new String(cs);
return result;
}
}
總結:
通過這個小實驗,使我深刻的體會到了守護進程的好處,其特點時當所有進程都爲守護進程的時候,擇關閉進程,這個小實驗就是進行了同時進行密碼猜測進程和日誌輸出進程,當猜測出密碼後,雖然說日誌還需要輸出進幾萬條數據,但是猶豫守護進程的特性,直接停止了所有進程。節省了時間與空間的浪費。