1.线程的创建和启动方式:
1.自定义类,让其继承Thread并重写run()方法,创建此类的对象。调用start()方法启动
public class MyThread extends Thread { //自定义线程类
@Override
public void run() {
。。。
}
}
MyThread t1 = new MyThread(); //创建
t1.start(); //启动
2.自定义类实现runnable接口,实现run()方法,创建Thread对象并传入这个实现类。调用start()方法启动
public class MyThread2 implements Runnable { //实现类
@Override
public void run() {
。。。
}
}
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r); //创建线程
t1.start(); // 启动
注意:只有Thread对象才有start()方法用于启动线程
2.线程之间数据共享
1.创建runnable实现类或继承Thread,重写run()方法:
public class MyRunnable implements Runnable {
private int count = 100; //要共享的变量
@Override
public void run() {
while (count > 0) {
try {
Thread.sleep(100);
count --;
System.out.println(count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2.创建多个线程,
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
此时t1,t2共享了变量count
注意:这里有线程安全问题
3.Thread的方法:
Thread.currentThread() //静态方法,获取当前正在运行线程(执行此代码的线程)对象
isAlive() //检查线程是否处于活动状态,活动状态:线程已经启动且尚未停止
Thread.sleep() //静态方法,让当前线程(执行此代码的线程)休眠
getId() //获取线程的唯一标识
例子:
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r);
System.out.println(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getId());
System.out.println(t1.getName());
System.out.println(t1.getId());
Thread.sleep(1000);
System.out.println(t1.isAlive());
t1.start();
System.out.println(t1.isAlive());
运行结果:
main
1
Thread-0
11
false
true
4.线程的停止
1. interrupt(); 用于停止线程的方法 //做了一件事:将线程停止状态的值置为了true
注意!!这里调用interrupt()方法停止线程,所谓停止线程并不是说线程执行完这个方法后就不执行了。调用此方法
仅仅是改变了线程的状态。线程中有一个标识线程是否停止的状态值。interrupt()方法将此值置为true,线程将继续往下执行。
例子:
System.out.println("执行前");
Thread.currentThread().interrupt();
System.out.println("执行后");
运行结果:
执行前
执行后 //调用interrupt方法后,线程依然在执行
2.查看停止状态的方法:
1. isInterrupted() //用于查看线程状态,返回boolean
例子:
System.out.println("执行前");
boolean status1 = Thread.currentThread().isInterrupted();
System.out.println(status1);
Thread.currentThread().interrupt();
boolean status2 = Thread.currentThread().isInterrupted();
System.out.println(status2);
System.out.println("执行后");
运行结果:
执行前
false //执行前为false
true //执行后为true
执行后
2.interrupted() //也是用于查看线程状态,为静态方法
例子:
System.out.println("执行前");
System.out.println(Thread.interrupted());
Thread.currentThread().interrupt();
System.out.println(Thread.interrupted()); //返回线程状态,并重置状态为false
System.out.println(Thread.interrupted()); //再次调用返回false,因为interrupted()返回线程状态的同时,会重置线程的状态为false
System.out.println("执行后");
运行结果:
执行前
false
true
false
执行后
注意:线程的状态初始值为false, 调用start()方法启动线程前是false, 执行完后,如果是true会被重置为false
因此,此状态值是在线程执行过程中才有意义。
3.两个方法的区别:
1.isInterrupted()为非静态方法,interrupted()为静态方法。isInterrupted()查看的是调用此方法的线程的状态
interrupted()查看的是执行当前行代码的线程的状态
2.isInterrupted()不会重置状态为false,interrupted()调用完会重置状态为false
4.sleep()方法与线程停止
当线程停止状态为true时,调用sleep会抛异常
调用sleep()进行线程休眠,在休眠过程中,如果线程停止状态由false变为true时,也会抛异常
例子:
Thread.sleep(1000);
System.out.println("执行前,状态:" + Thread.currentThread().isInterrupted());
Thread.currentThread().interrupt();
System.out.println("执行后,状态:" + Thread.currentThread().isInterrupted());
Thread.sleep(1000);
运行结果:
执行前,状态:false
执行后,状态:true
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.huawei.controller.ThreadController.main(ThreadController.java:31)
public class MyRunnable implements Runnable {
private int count = 100;
@Override
public void run() {
try {
System.out.println("线程执行");
Thread.sleep(1000); //休眠
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r);
t1.start();
t1.interrupt(); //线程休眠时,改变状态为true
运行结果:
线程执行
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.huawei.thread.MyRunnable.run(MyRunnable.java:18)
at java.lang.Thread.run(Thread.java:745)
5.让线程真正停止的方法,即不是改变停止状态,而是停止执行的方法:stop() //暴力终止线程执行,为已过时的方法
例子:
public class MyRunnable implements Runnable {
private int count = 100;
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
System.out.println("线程执行,循环次数:" + (i + 1));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r);
t1.start();
Thread.sleep(3000);
t1.stop();
运行结果:
线程执行,循环次数:1
线程执行,循环次数:2
线程执行,循环次数:3 //循环三次后,线程被终止,不再执行 //真正的停止
Process finished with exit code 0
调用slop()方法终止线程可能造成的问题:
1.可能使一些清理性的工作得不到完成
2.终止线程时会释放锁,这种释放是非正常释放,可能造成数据不一致问题。
6.不适用stop()完成线程终止:
采用停止状态进行控制,实现线程终止:如果停止状态为true,则抛出异常,或者使用return停止线程
例子:
public class MyRunnable implements Runnable {
private int count = 100;
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
System.out.println("线程执行,循环次数:" + (i + 1));
Thread.sleep(1000);
if (Thread.interrupted()) { //检查状态
throw new InterruptedException(); //如果问停止状态,则抛异常终止代码运行
//return; //或者使用return终止,此时也会抛出InterruptedException异常
}
}
} catch (InterruptedException e) {
System.out.println("线程终止,进行垃圾清理等工作。。。"); //线程执行停止后进行后续清理等工作
}
}
}
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r);
t1.start();
Thread.sleep(3000);
t1.interrupt(); //调用interrupt方法改变停止状态而不是暴力终止