Java自学-多线程 常见线程方法

Java 常见的线程方法

示例 1 : 当前线程暂停

Thread.sleep(1000); 表示当前线程暂停1000毫秒 ,其他线程不受影响
Thread.sleep(1000); 会抛出InterruptedException 中断异常,因为当前线程sleep的时候,有可能被停止,这时就会抛出 InterruptedException

package multiplethread;

public class TestThread {

public static void main(String[] args) {

Thread t1= new Thread(){
public void run(){
int seconds =0;
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.printf("已经玩了LOL %d 秒%n", seconds++);
}
}
};
t1.start();

}

}

示例 2 : 加入到当前线程中

首先解释一下主线程的概念
所有进程,至少会有一个线程即主线程,即main方法开始执行,就会有一个看不见的主线程存在。
在42行执行t.join,即表明在主线程中加入该线程
主线程会等待该线程结束完毕, 才会往下运行。

package multiplethread;

import charactor.Hero;

public class TestThread {

public static void main(String[] args) {

final Hero gareen = new Hero();
gareen.name = "盖伦";
gareen.hp = 616;
gareen.damage = 50;

final Hero teemo = new Hero();
teemo.name = "提莫";
teemo.hp = 300;
teemo.damage = 30;

final Hero bh = new Hero();
bh.name = "赏金猎人";
bh.hp = 500;
bh.damage = 65;

final Hero leesin = new Hero();
leesin.name = "盲僧";
leesin.hp = 455;
leesin.damage = 80;

Thread t1= new Thread(){
public void run(){
while(!teemo.isDead()){
gareen.attackHero(teemo);
}
}
};

t1.start();

//代码执行到这里,一直是main线程在运行
try {
//t1线程加入到main线程中来,只有t1线程运行结束,才会继续往下走
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Thread t2= new Thread(){
public void run(){
while(!leesin.isDead()){
bh.attackHero(leesin);
}
}
};
//会观察到盖伦把提莫杀掉后,才运行t2线程
t2.start();

}

}

示例 3 : 线程优先级

当线程处于竞争关系的时候,优先级高的线程会有更大的几率获得CPU资源
为了演示该效果,要把暂停时间去掉,多条线程各自会尽力去占有CPU资源
同时把英雄的血量增加100倍,攻击减低到1,才有足够的时间观察到优先级的演示
如图可见,线程1的优先级是MAX_PRIORITY,所以它争取到了更多的CPU资源执行代码

![线程优先级]( https://img-blog.csdnimg.cn/20190620073226726.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2plZGR6ZA==,size_16,color_FFFFFF,t_70)

package charactor;

import java.io.Serializable;

public class Hero{
public String name;
public float hp;

public int damage;

public void attackHero(Hero h) {
//把暂停时间去掉,多条线程各自会尽力去占有CPU资源
//线程的优先级效果才可以看得出来
// try {
//
// Thread.sleep(0);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
h.hp-=damage;
System.out.format("%s 正在攻击 %s, %s的血变成了 %.0f%n",name,h.name,h.name,h.hp);

if(h.isDead())
System.out.println(h.name +"死了!");
}

public boolean isDead() {
return 0>=hp?true:false;
}

}

package multiplethread;

import charactor.Hero;

public class TestThread {

public static void main(String[] args) {

final Hero gareen = new Hero();
gareen.name = "盖伦";
gareen.hp = 6160;
gareen.damage = 1;

final Hero teemo = new Hero();
teemo.name = "提莫";
teemo.hp = 3000;
teemo.damage = 1;

final Hero bh = new Hero();
bh.name = "赏金猎人";
bh.hp = 5000;
bh.damage = 1;

final Hero leesin = new Hero();
leesin.name = "盲僧";
leesin.hp = 4505;
leesin.damage = 1;

Thread t1= new Thread(){
public void run(){

while(!teemo.isDead()){
gareen.attackHero(teemo);
}
}
};

Thread t2= new Thread(){
public void run(){
while(!leesin.isDead()){
bh.attackHero(leesin);
}
}
};

t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();

}

}

示例 4 : 临时暂停

当前线程,临时暂停,使得其他线程可以有更多的机会占用CPU资源

package multiplethread;

import charactor.Hero;

public class TestThread {

public static void main(String[] args) {

final Hero gareen = new Hero();
gareen.name = "盖伦";
gareen.hp = 61600;
gareen.damage = 1;

final Hero teemo = new Hero();
teemo.name = "提莫";
teemo.hp = 30000;
teemo.damage = 1;

final Hero bh = new Hero();
bh.name = "赏金猎人";
bh.hp = 50000;
bh.damage = 1;

final Hero leesin = new Hero();
leesin.name = "盲僧";
leesin.hp = 45050;
leesin.damage = 1;

Thread t1= new Thread(){
public void run(){

while(!teemo.isDead()){
gareen.attackHero(teemo);
}
}
};

Thread t2= new Thread(){
public void run(){
while(!leesin.isDead()){
//临时暂停,使得t1可以占用CPU资源
Thread.yield();

bh.attackHero(leesin);
}
}
};

t1.setPriority(5);
t2.setPriority(5);
t1.start();
t2.start();

}

}

示例 5 : 守护线程

守护线程的概念是: 当一个进程里,所有的线程都是守护线程的时候,结束当前进程。

就好像一个公司有销售部,生产部这些和业务挂钩的部门。
除此之外,还有后勤,行政等这些支持部门。

如果一家公司销售部,生产部都解散了,那么只剩下后勤和行政,那么这家公司也可以解散了。

守护线程就相当于那些支持部门,如果一个进程只剩下守护线程,那么进程就会自动结束。

守护线程通常会被用来做日志,性能统计等工作。

package multiplethread;

public class TestThread {

public static void main(String[] args) {

Thread t1= new Thread(){
public void run(){
int seconds = 0;

while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.printf("已经玩了LOL %d 秒%n", seconds++);

}
}
};
t1.setDaemon(true);
t1.start();

}

}

练习破解密码

  1. 生成一个长度是3的随机字符串,把这个字符串当作 密码

  2. 创建一个破解线程,使用穷举法,匹配这个密码

  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) {
                    // TODO Auto-generated catch block
                    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;
    }
 
}

posted on 2020-02-26 17:41  半米高峰  阅读(287)  评论(0)    收藏  举报

导航