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资源执行代码

  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;
} }

Java自学-多线程 常见线程方法的更多相关文章

  1. Java:多线程,线程同步,同步锁(Lock)的使用(ReentrantLock、ReentrantReadWriteLock)

    关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨Lock对象. synchronize ...

  2. Java自学-多线程 启动一个线程

    Java 创建一个线程的三种方式 多线程即在同一时间,可以做多件事情. 创建多线程有3种方式,分别是继承线程类,实现Runnable接口,匿名类 步骤 1 : 线程概念 首先要理解进程(Process ...

  3. Java 基础 多线程和线程池基础

    一,多线程 1.1 多线程介绍 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程:线程是进程中的一个执行单元,负 ...

  4. Java创建多线程和线程安全集合Vector

    public class Test { public static Vector<String> data = new Vector<String>(); public sta ...

  5. Java自学-多线程 线程安全的类

    Java常见的线程安全相关的面试题 步骤 1 : HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式 区别1: HashMap可以 ...

  6. java核心-多线程(4)-线程类基础知识

    1.并发 <1>使用并发的一个重要原因是提高执行效率.由于I/O等情况阻塞,单个任务并不能充分利用CPU时间.所以在单处理器的机器上也应该使用并发. <2>为了实现并发,操作系 ...

  7. java学习之创建线程方法二

    我们上一节当中讲到了创建线程的第一种方法,就是继承Thread类,覆写Thread当中的run方法,然后创建子类对象,之后调用对象的start方法启动线程.但是这种方法有一个缺陷,因为我们知道在jav ...

  8. Java:多线程,线程池,使用CompletionService通过Future来处理Callable的返回结果

    1. 背景 在Java5的多线程中,可以使用Callable接口来实现具有返回值的线程.使用线程池的submit方法提交Callable任务,利用submit方法返回的Future存根,调用此存根的g ...

  9. java核心技术-多线程之线程内存模型

    对于每一种编程语言,理解它的内存模型是理所当然的重要.下面我们从jvm的内存模型来体会下java(不限java语言,严格来讲是JVM内存模型,所有JVM体系的变成语言均适用)的内存模型. 堆: 就是我 ...

随机推荐

  1. ssm项目中中文字符乱码

    昨天给同学改一个错,在SSM项目中,表单输入的String类型中,中文字符值,总是乱码,在控制器层获取的数据就开始乱码,先后进行了如下排查: web.xml中配置设置字符编码的监听器(过滤器), js ...

  2. 美食家App开发日记5

    今天将ListView控件用更强大的Recyclerview控件取代,最后调试了程序. 感觉Android编程难度实在是远远高于javaweb,初次接触,感觉有很多东西想实现,想得很容易,但是实现起来 ...

  3. 关于github显示不出来图片的问题

    今天打开github,突然发现图标图片等都显示不出来了. 控制台看了一下 百度查找了Failed to load resource: net::ERR_CERT_COMMON_NAME_INVALID ...

  4. SIR模型预测新冠病毒肺炎发病数据

    大家还好吗? 背景就不用多说了吧?本来我是初四上班的,现在延长到2月10日了.这是我工作以来时间最长的一个假期了.可惜哪也去不了.待在家里,没啥事,就用python模拟预测一下新冠病毒肺炎的数据吧.要 ...

  5. 异想家Win10常用的软件推荐

    本文总结一下自己日常使用Win10中涉及到的好用小软件,那些装机必备的软件在这里就不一一列出了.我重点想推荐一些自己觉得好用,符合自己偏好,但又不是每个人都知道的小工具: Rolan:一款类似于Win ...

  6. 【自制操作系统06】终于开始用 C 语言了,第一行内核代码!

    一.整理下到目前为止的流程图 写到这,终于才把一些苦力活都干完了,也终于到了我们的内核代码部分,也终于开始第一次用 c 语言写代码了!为了这个阶段性的胜利,以及更好地进入内核部分,下图贴一张到目前为止 ...

  7. pku-3321 Apple Tree(dfs序+树状数组)

    Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow ...

  8. Shell常用命令之yum

    介绍 yum命令是在Fedora和RedHat以及SUSE中基于rpm的软件包管理器,它可以使系统管理人员交互和自动化地更细与管理RPM软件包,能够从指定的服务器自动下载RPM包并且安装,可以自动处理 ...

  9. 2019年,我花了3个月时间备考PMP

    ​ 经过几个月的准备,终于在2019年12月7日完成了PMP的考试,并于1月21日查到了成绩,喜获5A,意料之中.总结这次考试的具体情况:涉及题型虽然都没有超出大纲的范围,但是原题出现的概率似乎不高, ...

  10. 今天更新IDEA后,我依旧要永久激活(支持2019.3.3版本)

    起因 今天一早用IDEA写代码,看到有下角有提示更新,有点强迫症的我,就手欠的又点了下更新,结果尼玛悲剧了,居然许可证过期,IDEA过期了,如下图所示: 就想用下新功能,就这样对我,就给两天的使用时间 ...