使用多线程
继承Thread类
class MyThread extends Thread{
@Override
public void run() {
super.run();
for (int i = 0; i <1000 ; i++) {
System.out.println(Thread.currentThread().getId());
}
}
}
启动线程需要使用start方法 ,而不能用run方法。
new MyThread().start();
实现Runnable接口
class MyThread implements Runnable{
@Override
public void run() {
System.out.println("外部类线程启动");
}
}
启动线程也是通过start方法启动的
MyRunnable runnable = new MyRunnable();
Thread thread=new Thread(runnable);
thread.start();
因为Runnable接口只有一个方法,因此也可以用匿名内部类的方式启动
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类线程启动");
}
}).start();
线程安全问题
currentThread()方法
currentThread方法可以返回代码段正在被哪个线程调用的信息。
Thread.currentThread
isAlive
判断当前线程是否处于活动状态
sleep
方法sleep的作用是在指定的毫秒数内让当前“正在执行的线程”休眠。 这个“正在执行的线程”是指this.currentThread()返回线程。
getId
getId作用是取得线程的唯一标识
停止多线程
停止一个线程可以使用Thread.stop方法,但是最好不要使用它,这个方法是不安全的,并且已经被deprecated。
停止一个线程的操作应该使用Thread.interrupt,但是记住这个方法不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的停止。
简单的来说,java中有三种方法可以终止正在运行的线程:
- 使用退出标志,使线程正常退出,即run方法完成后线程终止
- 使用stop方法强行终止线程,不推荐使用
- 使用interrupt方法中断线程。
使用interrupt停止线程
首先需要知道两个方法:
- this.isInterrupted : 测试线程是否已经中断
直接调用interrupt方法并不会终止线程,需要在线程代码中通过isInterrupted()方法判断线程是否已经中断,然后主动中断线程。
public class ApplicationTest {
public static void main(String [] args){
try {
MyRunnable runnable = new MyRunnable();
Thread thread=new Thread(runnable);
thread.start();
thread.sleep(100);
thread.interrupt();
}catch (InterruptedException e){
}
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
System.out.println("i="+(i+1));
if (Thread.currentThread().isInterrupted()){
System.out.println("已经停止了");
break;
}
}
}
}
yield方法
yiled方法的作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间。但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片。
线程的优先级
在操作系统中,线程可以化为优先级,优先级高的线程得到的CPU资源较多,也就是CPU优先执行的优先级较高的线程对象中的任务。
java中优先级分为1~10这个10哥登记,如果不在这个范围内就会抛出throw new IllegalArgumentException
线程的优先级具有继承性,比如A线程启动B线程,B的优先级与A一样
守护线程
在java线程中又两种线程,一种是用户线程,另一种是守护线程
守护线程: 任何一个守护线程都是整个JVM中所有非守护线程的“保姆”,只要当前JVM实例中存在任何一个非守护线程没有结束,守护线程就在工作,只有当最后一个非守护线程结束时,守护线程才随着JVM一同结束工作。Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是GC(垃圾回收器),它就是一个很称职的守护者。
可以通过thread.setDaemon(true)将线程设置为守护线程。