一、join()方法:执行该线程的方法进入阻塞状态,直到调用join方法的线程结束后,执行该方法的线程才会由阻塞状态转为就绪状态,再次与其他的线程争夺CPU的执行权,实例如下:
package com.jd.test;
import java.util.Date;
/**
*
* 计数器线程
*
*/
class CounterThread extends Thread{
private TimeThread timethread;
public CounterThread(TimeThread timethread) {
this.timethread=timethread;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
if(i==1) {
try {
timethread.join();//此时执行该方法的是计数器线程,因此当执行到i==1的时候,计数器线程会进入阻塞状态,直到调用join方法的时间线程结束,计数器线程才会重新进入就绪状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("计数器线程");
}
}
}
/**
*
* 时间线程
*/
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();
}
}
}
}
public class Test {
public static void main(String[] args) {
TimeThread timethread = new TimeThread();
timethread.start();
new CounterThread(timethread).start();
}
}
运行结果如图所示:
:特别注意:如果调用join()方法的线程,没有执行start方法,则永远不会执行该线程,实例如下:
package com.jd.test;
import java.util.Date;
/**
*
* 计数器线程
*
*/
class CounterThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 3; i++) {
if(i==1) {
try {
new TimeThread().join();//此时执行该方法的是计数器线程,由于时间线程么有调用start方法,因此不会执行时间线程;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("计数器线程"+new 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();
}
}
}
}
public class Test {
public static void main(String[] args) {
new CounterThread().start();
}
}
运行结果:
二、interrupt方法
实例:
package com.jd.test;
import java.util.Date;
/**
*
* 计数器线程
*
*/
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("计数器线程提前结束阻塞状态"+new Date());
}
}
System.out.println("计数器线程:"+i+":"+new 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();
}
}
}
}
public class Test {
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方法致使该计数器线程提前结束阻塞状态。
}
}
运行结果:
三、currentThread方法:返回当前正在执行的线程对象。
实例1:
package com.jd.test;
public class Test {
public static void main(String[] args) {
Thread thread1 = Thread.currentThread();//当前执行main方法的线程对象是主线程
System.out.println(thread1+"@@@@@@@@@@@@@@@@");
Thread thread2 = new TimeThread();//当前执行的线程对象是时间线程,即输出的Thread-0
System.out.println(thread2+"*****************");
thread2.start();
}
}
class TimeThread extends Thread{
@Override
public void run() {
Thread thread = Thread.currentThread();//当前run方法的线程对象是时间线程,与Test中的时间线程是统一个线程,因此输出都是Thread-0
System.out.println(thread+"&&&&&&&&&&&&&&&&");
}
}
运行结果:
实例2:
public class Test {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread();
System.out.println("########"+timeThread);//输出时间线程,########Thread[Thread-0,5,main]
timeThread.start();//此时执行run方法的线程对象是时间线程,因此输出@@@@@@@@Thread[Thread-0,5,main]
timeThread.run();//可以看成只是普通类调用方法,有主线程执行,一次执行run方法的线程对象是主线程,输出为@@@@@@@@Thread[main,5,main]
}
}
class TimeThread extends Thread{
@Override
public void run() {
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();//当执行该行代码时,打印线程会阻塞,此时会立马执行下一行代码,持续主线程并没有接受,因此输出为true,执行完输出语句,主线程结束,而此时打印线程并没有结束,因此输出为false,由此可证明,main方法中启动的线程可能晚于主线程结束
System.out.println("$$$$$$$$$$$$$$$$$$main线程状态:"+thread.isAlive());//这一行代码执行完,主线程也结束
}
}
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());//main方法中启动的线程可能晚于主线程结束
}
}
运行结果:
五、setDaemon方法:用于将一个尚未调用线程start方法的线程设置为守护线程,守护线程会随着最后一个非守护线程的结束而结束,进程也会随着最后一个非守护线程的结束而结束,进程中所启动的其他非守护线程不会随着某一个非守护线程的结束而结束
public class Test {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread();
timeThread.setDaemon(true);//守护线程
timeThread.start();
}
}
class TimeThread extends Thread{
@Override
public void run() {
while (true) {
System.out.println(111);
}
}
}
六、void setPriority(int newPriority):设置线程的优先级,优先级越高获得的执行次数越多
注意:同一个线程类创建的线程对象,优先级越高则可获得的执行次数越多;如果是不同的线程类创建的线程对象,优先级越高执行的次数不一定多,这与run()方法代码的复杂度有关
示例1:
public class Test {
public static void main(String[] args) {
TimeThread timeThread1 = new TimeThread("线程1");
timeThread1.start();
TimeThread timeThread2 = new TimeThread("线程2");//此时的线程1和线程2是同一个线程类创建的对象,run方法代码的复杂一样,把线程2的优先级设为10,优先级比线程1高,获得的执行次数也就越多
timeThread2.setPriority(10);
timeThread2.start();
}
}
class TimeThread extends Thread{
public TimeThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i <5; i++) {
System.out.println(getName()+":"+i);
}
}
}
示例2:
public class Test {
public static void main(String[] args) {
TimeThread timeThread = new TimeThread("线程1");
timeThread.start();
CountThread countThread = new CountThread("线程2");//此时的线程1和线程2不是同一个线程类创建的对象,run方法代码的复杂不一样,就算把线程2的优先级设为10,优先级比线程1高,获得的执行次数也不一定多,它与代码的复杂度有关
countThread.setPriority(10);
countThread.start();
}
}
class TimeThread extends Thread{
public TimeThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i <5; i++) {
System.out.println(getName()+":"+new Date()+new Date()+new Date()+new Date()+new Date()+new Date()+new Date()+new Date());
}
}
}
class CountThread extends Thread{
public CountThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i <5; i++) {
System.out.println(getName()+":"+i);
}
}
}