join方法:
执行该方法的线程进入阻塞状态,直到调用该方法的线程结束后再由阻塞转为就绪状态。
import java.util.Date;
class TimeThread extends Thread{
@Override
public void run() {
for(int i=0;i<=2; i++){
System.out.println("时间线程:"+new Date());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class CounterThread extends Thread {
private TimeThread timeThread;
public CounterThread(TimeThread timeThread){
this.timeThread = timeThread;
}
@Override
public void run() {
for(int i=1;i<=3; i++){
if(i==2){
try {
timeThread.join();//CounterThread线程执行join方法,所以CounterThread阻塞,直到timeTread线程结束。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("计数器线程:"+i);
}
}
}
public class Program {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread();
timeThread.start();
new CounterThread(timeThread).start();
}
}
结果:
注意:线程对象在调用join方法前必须先调用start方法,否则该线程永远不会进入执行状态。
interrupt方法:
结束线程在调用Object类的wait方法或该类的join方法、sleep方法过程中的阻塞状态,并在调用wait、join和sleep方法处产生InterruptedException异常。
import java.text.SimpleDateFormat;
import java.util.Date;
class TimeThread extends Thread {
public void run() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:sss");
String beforeTime = sdf.format(new Date());
System.out.println("beforeTime:"+beforeTime);
try {
sleep(30000);// 30秒后执行后面代码
} catch (Exception e) {
System.out.println("程序捕获了InterruptedException异常!");
}
String afterTime = sdf.format(new Date());
System.out.println("afterTime:"+afterTime);
}
}
public class Program {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread();
timeThread.start();
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
timeThread.interrupt();
}
}
结果:
理论上beforeTime和afterTime应该相差30秒,但因为该线程类的对象在1秒后执行了interrupt方法而使得该线程对象提前结束了阻塞状态,从而导致了beforeTime和afterTime相差少于30秒
import java.util.Date;
class TimeThread extends Thread{
@Override
public void run() {
for(int i=0;i<=2; i++){
System.out.println("时间线程:"+new Date());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class CounterThread extends Thread {
private TimeThread timeThread;
public CounterThread(TimeThread timeThread){
this.timeThread = timeThread;
}
@Override
public void run() {
for(int i=1;i<=3; i++){
if(i==2){
try {
timeThread.join();
} catch (InterruptedException e) {
System.out.println("计数器线程提前结束阻塞状态");
}
}
System.out.println("计数器线程:"+i);
}
}
}
public class Program {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread();
timeThread.start();
CounterThread counterThread = new CounterThread(timeThread);
counterThread.start();
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
counterThread.interrupt();//计数器线程执行该行代码后进入阻塞状态,时间线程至少需要消耗30秒才能结束,而15秒后计数器线程调用了interrupt方法致使该计数器线程提前结束阻塞状态。
}
}
结果:
计数器线程执行该行代码后进入阻塞状态,时间线程至少需要消耗30秒才能结束,而15秒后计数器线程调用了interrupt方法致使该计数器线程提前结束阻塞状态。
currentThread方法:
返回当前正在执行的线程对象。
public class Test {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread();
System.out.println("########"+timeThread);
timeThread.start();//输出中thread为时间线程
timeThread.run();//输出中thread为主线程
}
}
class TimeThread extends Thread{
@Override
public void run() {
Thread thread = Thread.currentThread();
System.out.println("@@@@@@@@"+thread);
}
}
public class Test {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread();
System.out.println("########"+timeThread);
timeThread.start();//输出中thread为时间线程
timeThread.main();//输出中thread为主线程
}
}
class TimeThread extends Thread{
@Override
public void run() {
main();
}
void main(){
Thread thread = Thread.currentThread();
System.out.println("@@@@@@@@"+thread);
}
}
isAlive方法:
判定该线程是否处于就绪、运行或阻塞状态,如果是则返回true,否则返回false。
public class Test {
public static void main(String[] args) {
Thread thread = Thread.currentThread();
new PrintThread(thread).start();
System.out.println("main线程状态:"+thread.isAlive());//为true
}
}
class PrintThread extends Thread{
private Thread thread;
public PrintThread(Thread thread){
this.thread = thread;
}
@Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println("main线程状态:"+thread.isAlive());//为false
}
}
setDaemon方法:
用于将一个尚未调用线程start方法的线程设置为守护线程。守护线程主要用于为其他线程的运行提供服务(Java中的垃圾回收机制就是守护线程),这种线程属于创建它的线程。
1.守护线程随着最后一个非守护线程的终止而终止,如下代码:
public class Program {
public static void main(String[] args) {
CounterThread counterThread = new CounterThread();
counterThread.setDaemon(true);
counterThread.start();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class CounterThread extends Thread {
public void run() {
int i=1;
while(true){
System.out.println("计数器:"+i);
i++;
}
}
}
2.进程中所启动的其他非守护线程不会随着某一个非守护线程的结束而结束,如下代码:
import java.util.Date;
public class Test {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread();
timeThread.start();
}
}
class TimeThread extends Thread{
@Override
public void run() {
System.out.println("时间线程,当前时间:"+new Date());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
CounterThread counterThread = new CounterThread();
//counterThread.setDaemon(true);
counterThread.start();//10秒后“任务管理器”中javaw.exe进程中多一条线程——计数器线程
try {
Thread.sleep(5000);//一个时段后“任务管理器”中javaw.exe进程中少一条线程(时间线程),但计数器线程依然在工作
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class CounterThread extends Thread {
public void run() {
for (int i = 1; ; i++) {
System.out.println("计数器线,当前i的值:"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3.进程随着最后一个非守护线程的结束而结束,如下代码:
import java.util.Date;
public class Test {
public static void main(String[] args) {
TimeThread time = new TimeThread();
time.start();
}
}
class TimeThread extends Thread{
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("时间线程:"+new Date());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
void start():使该线程开始启动,Java 虚拟机负责调用该线程的 run() 方法。多次启动一个线程是非法的。
void sleep(long millis):Thread类静态方法,线程进入阻塞状态,在指定时间(单位为毫秒)到达之后进入就绪状态(Runnable),而非立即进入执行状态。
void yield():静态方法,当前线程放弃占用CPU资源,回到就绪状态,使其他优先级不低于此线程的线程有机会被执行。
void setPriority(int newPriority):设置当前线程的优先级,线程优先级越高,线程获得执行的次数越多,Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:
static int MAX_PRIORITY 最高优先级值为10;
static int NORM_PRIORITY 默认优先级值为5;
static int MIN_PRIORITY 最低优先级值为1;
注意:同一个线程类创建的多个线程,线程优先级越高的线程获得的执行次数极有可能越多;但是不同线程类创建的线程,线程优先级越高,执行次数不一定越多,这个run方法的代码复杂度有关。
int getPriority():获得当前线程的优先级。