多线程
1. 创建线程的方式
public static void main(String[] args)
{
//1.显示继承Thread类,重写run方法
myThread t1 = new myThread();
t1.start();//启动线程
//2.使用匿名内部类实现 Thread接口
Thread t2 = new Thread()
{
@Override
public void run()
{
System.out.println("使用匿名内部类实现 Thread接口");
}
};
//3.实现Runnable接口
Thread t3 = new Thread(new myRunnable());
t3.start();
//4.使用匿名内部类实现Runnable接口
Runnable runnable = new Runnable()
{
@Override
public void run()
{
System.out.println("使用匿名内部类实现Runnable接口");
}
};
Thread t4 = new Thread(runnable);
t4.start();
}
//1.显示继承Thread类,重写run方法
static class myThread extends Thread
{
@Override
public void run()
{
System.out.println("显示继承Thread类,重写run方法");
}
}
//3.实现Runnable接口
static class myRunnable implements Runnable
{
@Override
public void run()
{
System.out.println("实现Runnable接口");
}
}
2. 线程的6种状态
2.1 NEW(新建)
当用new操作符创建一个新线程时,如new Thread®,该线程还没有开始运行。这意味着它的状态是new。当一个线程处于新创建状态时,程序还没有开始运行线程中的代码。在线程运行之前还有一些基础工作要做。
2.2 Runnable(可运行)
一旦调用start方法,线程将处于runnable状态。一个可运行的线程可能正在运行也可能没有运行,这取决于操作系统给线程提供运行的时间。(Java的规范说明没有将它作为一个单独状态。一个正在运行中的线程仍然处于可运行状态)
在任何给定时刻,一个可运行的线程可能正在运行也可能没有运行(这就是为什么将这个状态称为可运行而不是运行。
2.3 Blocked(阻塞)
当一个线程试图获取一个内部的对象锁,而该锁被其他线程持有,则该线程进入阻塞状态。
2.4 Waiting(等待)
当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。
2.5 Timed waiting(计时等待)
有几个方法有一个超时参数。调用它们导致线程进入计时等待态。这一状态将一直保持到超时期满或者接收到适当的通知。
2.6 Terminated(终止)
线程已经结束,但是其对象还未被销毁
3.线程属性
3.1 中断线程
当对一个线程调用interrupt方法时,就会设置线程中断状态。这是每个线程都有的boolean标志
我们在中断线程时有两种方式,一种是等待当前线程本次任务结束后再中断,一种则是遇到 interrupt方法 后立即中断
我们以转账为例,代码如下
方式1:
static boolean isQuit = false;
public static void main(String[] args)
{
Thread t1 = new Thread()
{
@Override
public void run()
{
while (!isQuit)
{
System.out.println("正在转账");
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
};
t1.start();//启动线程
try
{
//让主线程休眠5000ms
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("终止交易");
//温和方式结束线程
isQuit = true;
}
方式2:
public static void main(String[] args)
{
Thread t1 = new Thread()
{
@Override
public void run()
{
//Thread.currentThread().isInterrupted() 判断当前线程是否设置了中断状态
while (!Thread.currentThread().isInterrupted())
{
System.out.println("正在转账");
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
break;
}
}
}
};
t1.start();
try
{
//让main方法的线程休眠5000
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("终止交易");
//立即中断线程
t1.interrupt();//设置中断状态为true
}
如果线程被阻塞,就无法检测中断状态。这是产生 InterruptedException异常的地方。当在一个被阻塞的线程(调用sleep或wait)上调用interrupt方法时,阻塞调用将会被Interrupted Exception 异常中断。