一、创建线程的两种方式
1、继承Thread类
public class MyThreadClass extends Thread {
@Override
public void run() {
System.out.println("MyThreadClass ...");
}
}
2、实现Runnable接口,重写run方法
public class MyThreadInterface implements Runnable{
@Override
public void run() {
System.out.println("MyThreadInterface ...");
}
}
二、启动线程
Thread类的构造方法蛮多,下面是几个比较常用的。
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
//Thread类实现Runnable接口,这里也可以传入Thread的子类
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
//name为线程名称
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
通过一定要通过start()方法启动线程,如果通过run()方法启动,就变成同步执行了。
public static void main(String[] args) {
MyThreadClass t1 = new MyThreadClass();
t1.start();
Thread t2 = new Thread(new MyThreadInterface());
t2.start();
Thread t3 = new Thread(new MyThreadClass());
t3.start();
}
三、几个常用的方法
currentThread() //当前线程
isAlive() //判断当前线程是否处于激活状态
sleep() //线程休眠,单位秒
getId() //线程的ID
下面一段代码,运用了上面几个方法:
public static void main(String[] args) {
try {
MyThreadClass t1 = new MyThreadClass();
Thread t2 = new Thread(new MyThreadInterface());
Thread t3 = new Thread(new MyThreadClass());
t1.start();
Thread.sleep(1000); //1
t2.start();
System.out.println("t2's id is : " + t2.getId()); //2
t3.start();
System.out.println("t3's id is : " + t3.getId());
System.out.println("thread t1 is alive: " + t1.isAlive());
System.out.println("thread " + Thread.currentThread().getName() //3
+ " is alive: " + Thread.currentThread().isAlive());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
注释解释:
1、 Thread.sleep(1000);当前正在运行的线程休眠1s,上述即main线程休眠1s钟
2、取得当前线程的唯一ID
3、当前正在运行的是main线程,所以main线程是激活状态,而t1线程已经执行完,所以t1线程不是激活状态
运行结果
四、停止线程
停止线程的三种方式:
1、使用退出标志,使线程正常退出,即run()方法执行完后线程终止
2、使用stop方法强行停止线程,目前已经作废,不讨论了
3、使用interrupt()方法改变正在运行的线程状态,同时需要在线程中根据线程状态,来终止线程
(换个说法,给这个线程打个标记,告诉他自己,你要废了,他自己获取到这个标记后,喝点敌敌畏,直接挂了)
这里主要看第3种方式如何实现停止线程的。说到停止线程,就不得不说的两个方法interrupted()和isInterrupted().
对比:
interrupted()静态方法
测试当前线程是否为中断状态,执行后,将状态标志更改为false,即执行后,线程就不是中断状态了。
isInterrupted()实例方法
仅测试线程是否为中断状态,不更改状态标志
public static void main(String[] args) {
Thread.currentThread().interrupt();
System.out.println(Thread.interrupted()); //true
System.out.println(Thread.interrupted()); //false
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().isInterrupted()); //true
System.out.println(Thread.currentThread().isInterrupted()); //true
}
上述第3种方法主要有两个步骤:
1、通过interrupt()方法给正在运行的线程打上中断标记
2、线程内部根据标记来自行停止
package hccool;
/**
* @author hgh
* @Package hccool
* @createDate 2020/04/27 14:14
*/
public class TestInterruptMethod {
public static void main(String[] args) {
try {
InterruptMethodManager thread = new InterruptMethodManager();
thread.start();
Thread.sleep(1000);
thread.interrupt(); //在线程启动1s后给其打了个残废标记
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class InterruptMethodManager extends Thread {
@Override
public void run() {
for (int i = 0; i < 30 * 10000; i++) {
//判断当前是否打了终止标记。如果是,通过抛异常退出(有其他种方式终止,建议抛异常的方式)
if (this.isInterrupted()) {
throw new RuntimeException("stop thread success!");
}
System.out.println("current i is :" + i);
}
System.out.println("如果线程成功终止,那么这句话不会被输出...");
}
}
}
控制台输出的结果如下,线程成功终止停下来了。
五、线程的优先级
几个特性:
1、继承性(传递)
A线程启动B线程,则B线程的优先级与A保持一致
2、规则性
高优先级的线程总是大部分先执行完,但不是全部先执行完
3、随机性
高优先级的线程总是大部分先执行完,但不是全部先执行完,剩下那部分屌丝逆袭成功的就代表了随机性
package hccool;
/**
* @author hgh
* @Package hccool
* @createDate 2020/04/27 14:38
*/
public class TestPriority {
public static void main (String[] args){
ThreadA a = new ThreadA();
ThreadB b = new ThreadB();
a.setPriority(Thread.MAX_PRIORITY);
b.setPriority(Thread.MIN_PRIORITY);
a.start();
b.start();
}
static class ThreadA extends Thread {
@Override
public void run() {
ThreadC c = new ThreadC();
c.start();
for (int i = 0; i < 100; i++) {
System.out.println("ThreadA: " + i);
}
}
}
static class ThreadB extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("ThreadB: " + i);
}
}
}
static class ThreadC extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("ThreadC: " + i);
}
}
}
}
每次运行的结果都不一致,但总体来说threadA 和 threadC优先threadB输出。
这一篇先这样咯~