多线程(Java)
Java中的“多线程”机制是指可以同时运行多个程序块(进程的多个路径)。
1.通过继承Thread类实现多线程
Thread类存放于java.lang类库里,java.lang包中提供常用的类、接口、一般异常、系统等编程语言的核心内容,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,Java系统默认加载(import)这个包,我们可以直接使用Thread类,而无需显示加载。
由于在Thread类中,已经定义了run()方法,因此,用户要想实现多线程,必须定义自己的子类,该子类继承于Thread类,同时要覆写Thread类中的run()方法。
public class ThreadDemo //同时激活多个线程
{
public static void main(String[] args)
{
new TestThread().start(); //激活一个线程,需要使用Thread类的start方法
for (int i=0; i<5;i++)
{
System.out.println("main线程在运行!");
try {
Thread.sleep(1000);//睡眠1秒
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
class TestThread extends Thread
{
public void run() //覆写父类的run方法
{
for(int i=0;i<5;i++)
{
System.out.println("TestThread在运行!");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果:
2.通过实现Runnable接口实现多线程
在Java中不允许多继承,如果一个类已经继承了其他类,那么这个类就不能继承Thread类,但一个类是可以继承多个接口的。如果一个类的子类想采用多线程技术,这时就要用到Runnable接口来创建线程。
public class RunnableThread //用Runnable接口实现多线程使用实例
{
public static void main(String[] args)
{
TestThread newTh = new TestThread(); //实例化TestThread类的一个对象newTh
new Thread(newTh).start(); //实例化一个Thread类的匿名对象,然后将TestThread类的对象
for(int i=0;i<5;i++) //newTh作为Thread类构造方法的参数,之后再调用这个匿名
{ //Thread类对象的start()方法启动多线程
System.out.println("main线程在运行!");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
class TestThread implements Runnable //TestThread类是多线程Runnable接口的实现类
{
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println("TestThread线程在运行!");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果为:
由运行结果可知,多线程的执行顺序存在不确定性。
3.两种多线程实现机制的比较
Thread类实现了Runnable接口,即在本质上,Thread类是Runnable接口众多的实现子类中的一个,它的地位其实和我们自己写一个Runnable接口的实现类,没有多大区别,所不同的是,Thread不过是官方提供的设计罢了。
例:使用Thread实现多线程模拟铁路售票系统(多线程资源共享)
public class RunnableThread
{
public static void main(String[] args)
{
TestThread newTh = new TestThread(); //启动4个线程,并实现资源共享
new Thread(newTh).start();
new Thread(newTh).start();
new Thread(newTh).start();
new Thread(newTh).start();
}
}
class TestThread extends Thread
{
private int tickets = 5;
public void run()
{
while(tickets > 0)
{
System.out.println(Thread.currentThread().getName() + "出售票" + tickets);
tickets -=1;
}
}
}
运行结果:
由运行结果可知,程序运行结果不唯一,事实上是产生了与时间有关的错误。。
4.Java8中运行线程的新方法
在Java8中新引入了Lambda表达式,使得创建线程的形式有所变化。示范代码如下:
Thread thread = new Thread(()-> {System.out.println("Java8");}).start();
例:利用Lambda表达式创建新线程
public class LambdaDemo
{
public static void main(String[] args)
{
Runnable task = ()->{
String threadName = Thread.currentThread().getName();
System.out.println("Hello " + threadName);
};
task.run(); //调用run()方法
Thread thread = new Thread(task);
thread.start();
System.out.println("Done!");
}
}
//第5-8行用lambda表达式实现了Runnable,同时在6-7行定义了run()方法,
//并定义了一个Runnable接口的对象task
运行结果:
Hello main
Done!
Hello Thread-0