一、两个实现多线程的方法
1、 直接继承Thread类, 然后重写run()方法。
2、 实现Runnable()接口, 重写run()方法。
推荐使用第二种方法。
二、 线程中的各种方法
1、 Thread.yield() 方法
* Thread.yield()方法,程序运行到这句话的时候,会让出当前线程,让其他线程执行,把执行权交给其他线程,使当前线程由运行状态变为可执行状态,但是并不是说下一次一定不是执行这个线程,而是CPU从可执行状态的线程中选一个运行。
public class PrintNum implements Runnable {
private int num;
public PrintNum(int num) {
this.num = num;
}
@Override
public void run() {
for(int i = 0 ; i < num ; i++) {
System.out.println(i);
/*
* Thread.yield()方法,程序运行到这句话的时候,会让出当前线程,让其他线程执行,
* 把执行权交给其他线程,使当前线程由运行状态变为可执行状态,但是并不是说下一次一
* 定不是执行这个线程,而是CPU从可执行状态的线程中选一个运行
*/
Thread.yield();
}
}
}
当程序运行到Thread.yield()方法时,该线程会让出CPU资源,进入可执行状态,也就是就绪状态,等待CPU分配资源。
2、 Thread.sleep() 方法
Thread.sleep()方法,传入一个参数,millis, 为一个int 类型的变量,为毫秒,让进程从运行状态进入中断状态, 经过millsecond毫秒之后,重新进入到线程队列变成可执行状态,等CPU分配。
3、 join()方法
实例方法, 调用该实例的join() 方法,就会将当前运行的线程阻塞住,等待调用join()方法的线程运行结束之后再重新运行该线程。
4、 interrupt() 方法 和Thread.interrupted() 方法
// Demo1.java
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
public class Demo1 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new PrintChar('A', 200));
// Thread t2 = new Thread(new PrintChar('B', 100));
// Thread t3 = new Thread(new PrintNum(100));
t1.start();
// t2.start();
// t3.start();
/*
* setPriority()方法,设置优先级,值为1 - 10,10 为最高, 但是并不是设置了低的优先级就最后执行,而是概率的问题
*/
// t1.setPriority(Thread.MAX_PRIORITY);
/*
* threadInstance.join()方法,阻塞当前线程,等threadInstance线程执行完毕之后再执行当前的线程
*/
for(int i = 0; i < 200 ; i++) {
System.out.println(i);
if (i == 50 ) {
/*
* interrupt()方法经常用来“吵醒” 休眠的线程, 当一些线程调用了sleep() 方法处于休眠状态的时候,
* 一个占有CPU资源的线程可以让休眠的线程跳用interrupt()方法“吵醒”自己,让线程结束休眠,重新排队
* 等待CPU的资源
*
* interrupt() 实际意义上是设置了一个标志位,并不能终止t1线程,只是通知t1线程把中断标志给修改一下,
* 中断标志平常是false,但是调用了interrupt()方法之后,变为true, 并不是直接把t1线程给终止了,t1
* 会不断检查这个标志位,看看是不是有人想要让线程终止,如果有人让线程终止,就停止,但是是否终止决定权
* 在t1受伤
*/
// t1.interrupt();
}
}
}
}
//PrintChar.java
public class PrintChar implements Runnable {
private char alpha;
private int times;
public PrintChar(char alpha, int times) {
this.alpha = alpha;
this.times = times;
}
@Override
public void run() {
/*
* Thread.sleep()方法,传入一个参数,millis, 为一个int 类型的变量,为毫秒,让进程从运行状态进入中断状态,
* 进过millsecond毫秒之后,重新进入到线程队列变成可执行状态,等CPU分配。
*/
try {
int i = 0;
for (i = 0; i < times; i++) {
// if(Thread.currentThread().isInterrupted()) {
// break;
// }
if(Thread.interrupted()) {
/*
* Thread.interrupted()静态方法,返回一个boolean类型,返回中断结果,查看是否有其他线程调用了(线程实例.interrupt())方法,
* 并重置该线程的中断标志位,变成false. (先返回之前的类型, 后重置为false)
*/
System.out.println(Thread.currentThread().isInterrupted());
}
System.out.println(alpha);
// if (i >= 50) {
// Thread.sleep(3000);
// }
}
System.out.println(i + " 打印完了");
} catch (Exception e) {
e.printStackTrace();
}
}
}
//PrintNum.java
public class PrintNum implements Runnable {
private int num;
public PrintNum(int num) {
this.num = num;
}
@Override
public void run() {
for(int i = 0 ; i < num ; i++) {
System.out.println(i);
/*
* Thread.yield()方法,程序运行到这句话的时候,会让出当前线程,让其他线程执行,
* 把执行权交给其他线程,使当前线程由运行状态变为可执行状态,但是并不是说下一次一
* 定不是执行这个线程,而是CPU从可执行状态的线程中选一个运行
*/
Thread.yield();
}
}
}