线程
线程用于并发执行多个任务。感官上像是”同时”执行
创建线程有两种方式。
方式一:
继承线程并重写run方法来定义线程要执行的任务代码
package day09;
/**
* 线程
* 线程用于并发执行多个任务。感官上像是"同时"执行
*
* 创建线程有两种方式。
* 方式一:
* 继承线程并重写run方法来定义线程要执行的任务代码
* @author adminitartor
*
*/
public class ThreadDemo1 {
public static void main(String[] args) {
Thread t1 = new MyThread1();
Thread t2 = new MyThread2();
/*
* 启动线程要调用start方法,不要直接调用
* run方法。
* 当线程启动后,被分配时间片开始运行时会
* 自动调用run方法。
*/
t1.start();
t2.start();
}
}
/**
* 第一种创建线程存在两个不足:
* 1:由于java是单继承,所以导致继承了Thread不能
* 在继承其他类,在实际开发中经常会出现继承冲突
* 问题
* 2:由于重写线程run方法,将线程要执行的任务定义
* 在了线程中,导致任务与线程有一个耦合关系,
* 不利于线程重用。
* @author adminitartor
*
*/
class MyThread1 extends Thread{
public void run(){
for(int i=0;i<1000;i++){
System.out.println("你是谁啊?");
}
}
}
class MyThread2 extends Thread{
public void run(){
for(int i=0;i<1000;i++){
System.out.println("我是查水表的!");
}
}
}
方式二:创建线程的方式
实现Runnable接口单独定义任务
package day09;
/**
* 方式二:创建线程的方式
* 实现Runnable接口单独定义任务
* @author adminitartor
*
*/
public class ThreadDemo2 {
public static void main(String[] args) {
Runnable r1 = new MyRunnable1();
Runnable r2 = new MyRunnable2();
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
class MyRunnable1 implements Runnable{
public void run(){
for(int i=0;i<1000;i++){
System.out.println("你是谁啊?");
}
}
}
class MyRunnable2 implements Runnable{
public void run(){
for(int i=0;i<1000;i++){
System.out.println("我是查水表的!");
}
}
}
用匿名内部类形式完成线程两种方式的创建
package day09;
/**
* 用匿名内部类形式完成线程两种方式的创建
* @author adminitartor
*
*/
public class ThreadDemo3 {
public static void main(String[] args) {
//方式一
Thread t1 = new Thread(){
public void run(){
for(int i=0;i<1000;i++){
System.out.println("你是谁啊?");
}
}
};
//方式二
Runnable runn = new Runnable(){
public void run(){
for(int i=0;i<1000;i++){
System.out.println("我是查水表的!");
}
}
};
Thread t2 = new Thread(runn);
t1.start();
t2.start();
}
}
线程提供了一个静态方法currentThread
该方法可以获取运行该方法的线程。
package day09;
/**
* 线程提供了一个静态方法currentThread
* 该方法可以获取运行该方法的线程。
* java中所有代码都是线程运行的,main方法也不例外。
* 当虚拟机启动后会创建一个线程来执行main方法。
* @author adminitartor
*
*/
public class Thread_CurrentThread {
public static void main(String[] args) {
//获取了运行main方法的线程
Thread main = Thread.currentThread();
System.out.println("运行main方法的线程是:"+main);
dosome();
//自定义线程
Thread t = new Thread(){
public void run(){
Thread t = Thread.currentThread();
System.out.println("自定义线程:"+t);
dosome();
}
};
t.start();
}
public static void dosome(){
Thread t = Thread.currentThread();
System.out.println("运行dosome方法的线程是:"+t);
}
}
线程提供了获取相关信息的方法
package day09;
/**
* 线程提供了获取相关信息的方法
* @author adminitartor
*
*/
public class Thread_Info {
public static void main(String[] args) {
//获取运行main方法的线程
Thread main = Thread.currentThread();
long id = main.getId();
System.out.println("id:"+id);
String name = main.getName();
System.out.println("name:"+name);
int priority = main.getPriority();
System.out.println("优先级:"+priority);
boolean isAlive = main.isAlive();
System.out.println("isAlive:"+isAlive);
//是否是守护线程
boolean isDaemon = main.isDaemon();
System.out.println("isDaemon:"+isDaemon);
//是否被中断
boolean isInterrupted = main.isInterrupted();
System.out.println("isInterrupted:"+isInterrupted);
}
}
线程的优先级
线程的优先级有10个等级,分别用数字1-10表示
其中1最低,10最高,5为默认值
package day09;
/**
* 线程的优先级
* 线程的优先级有10个等级,分别用数字1-10表示
* 其中1最低,10最高,5为默认值
* 也可以使用线程提供的常量:
* MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY
* @author adminitartor
*
*/
public class Thread_Priority {
public static void main(String[] args) {
Thread min = new Thread(){
public void run(){
for(int i=0;i<10000;i++){
System.out.println("min");
}
}
};
Thread max = new Thread(){
public void run(){
for(int i=0;i<10000;i++){
System.out.println("max");
}
}
};
Thread norm = new Thread(){
public void run(){
for(int i=0;i<10000;i++){
System.out.println("nor");
}
}
};
min.setPriority(Thread.MIN_PRIORITY);
max.setPriority(Thread.MAX_PRIORITY);
min.start();
norm.start();
max.start();
}
}
Thread提供了一个静态方法
static void sleep(long ms)
该方法可以让运行该方法的线程阻塞指定毫秒,当阻塞超时后线程会回到RUNNABLE状态等待再次并发运行
package day09;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Thread提供了一个静态方法
* static void sleep(long ms)
* 该方法可以让运行该方法的线程阻塞指定毫秒,当
* 阻塞超时后线程会回到RUNNABLE状态等待再次并发
* 运行
* @author adminitartor
*
*/
public class Thread_Sleep {
public static void main(String[] args) {
// 15:48:33
SimpleDateFormat sdf
= new SimpleDateFormat("HH:mm:ss");
while(true){
System.out.println(sdf.format(new Date()));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
守护线程
守护线程也称为:后台线程
package day09;
/**
* 守护线程
* 守护线程也称为:后台线程
* 使用上与普通线程没差别,但是结束时机上有所不同
* 当一个进程结束时,该进程中的所有守护线程都要强制
* 结束。
* 当一个进程中的所有前台线程(普通线程)都结束使,
* 进程结束。
* @author adminitartor
*
*/
public class Thread_Daemon {
public static void main(String[] args) {
Thread rose = new Thread(){
public void run(){
for(int i=0;i<10;i++){
System.out.println("rose:let me go!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("rose:啊啊啊啊啊啊AAAAAAAaaaa....");
System.out.println("音效:噗通!");
}
};
Thread jack = new Thread(){
public void run(){
while(true){
System.out.println("jack:you jump!i jump!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
rose.start();
//设置为后台线程,必须在start之前设置
jack.setDaemon(true);
jack.start();
}
}
线程提供了一个方法:void join()
该方法是用来协调线程间同步运行的。
异步:各干各的
同步:有先后顺序的执行
package day09;
/**
* 线程提供了一个方法:void join()
* 该方法是用来协调线程间同步运行的。
* 异步:各干各的
* 同步:有先后顺序的执行
* @author adminitartor
*
*/
public class Thread_Join {
//表示图片是否下载完完毕的状态
public static boolean isFinish = false;
public static void main(String[] args) {
final Thread download = new Thread(){
public void run(){
System.out.println("down:开始下载图片...");
for(int i=1;i<=100;i++){
System.out.println("down:"+i+"%");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
System.out.println("down:图片下载完毕!");
isFinish = true;
}
};
Thread show = new Thread(){
public void run(){
System.out.println("show:开始显示图片...");
//先等待下载完成将图片下载完毕
try {
/*
* show线程执行到join方法时会进入
* 阻塞状态,直到download线程执行
* 完毕,才会解除阻塞。
*/
download.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!isFinish){
throw new RuntimeException("图片没有下载完毕!");
}
System.out.println("show:显示图片完毕!");
}
};
download.start();
show.start();
}
}