黑马程序员--多线程
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、定义
进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径或叫控制单元。
线程:进程中的一个独立的控制单元。线程在控制着进程的执行。 一个进程中至少有一个线程。
二、多线程作用
优点:多任务共同进行,防止后任务在一定时间内执行不到的问题发生。
弊端:线程如果太多,会导致效率降低。
多线程内部执行方式:
1、多线程运行结果的随机性:多线程中,线程间都会获取cpu的执行权,cpu执行到谁,谁就运行。
明确一点:某一时刻,只能有一个程序在运行(多核除外)。
2、cpu在做着快速的切换,已达到看上去是同时运行的效果。所以当线程过多时,cpu的切换次数会增多,
造成运行效率降低。所以,多线程的运行行为可看成互相抢夺cpu的执行权。
3、JVM 启动的时候会有一个进程 java.exe. 该进程中至少一个线程负责java程序的执行。
而且这个线程运行的代码存在于main方法中。该线程称之为主线程。
4、JVM也是一个多线程。JVM运行不止启动一个主线程,还有负责启动垃圾回收机制。
三、自定义线程
1、线程运行状态:被创建、运行、临时状态、冻结、消亡五种状态。
2、创建线程方式:
第一种方式:继承Thread类。
步骤:
a、定义类继承Thread
b、复写Thread类中的run方法。原因:每个线程都有自己的目的性。JVM将创建的主线程任务定义在主函数中(main)。
run方法就是Java给用户用于创建自己任务的区域。
c、调用线程的start()。start()有两个作用:a、启动线程;b、让java虚拟机调用该函数的run方法。
//通过继承创建自己的线程
class Demo extends Thread
{
public void run()
{
for(int x=0;x<5;x++)
System.out.println("demo run--"+x);
}
}
class RunDemo
{
public static void main(String[] args)
{
//创建线程的目的:开启一条执行路径。可理解为抢夺资源。
Demo a = new Demo();
//开启线程并执行该线程的run方法。可理解为:赛跑的信号枪。
a.start();
//一般的对象调用方法。是一个强制性命令。系统会执行完run()后,再运行主函数。
//a.run();
for(int x=0;x<5;x++)
//用Thread类的getName()方法获取执行线程的名称。Thread.currentThread()==this;
System.out.println("Hellow World--"+x+this.getName());
}
}
多线程输出结果:
单线程执行结果:
第二种方式:实现Runnable接口。
该类实现run方法,然后可以分配该类的实例,在创建Thread时作为一个参数来传递并启动。
步骤:
a、定义类实现Runnable接口
b、覆盖Runnable接口中的run方法,将线程要运行的代码存放在该run方法中。
c、通过Thread类建立线程对象。
d、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
因为自定义的run方法所属的对象是Runnable接口的子类对象,所以要让线程去执行指定对象的run方法,
就必须明确该run方法所属对象。(让你儿子去打酱油,你必须告诉他超市在哪)
e、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
//实现Runnable,建立多线程
class Ticket implements Runnable //extends Thread
{
//此处可定义static让数据变成共享数据。但一般不定义static,因为其寿命太长。
private int tick = 100;
public void run()
{
//while(true):无限循环,增加问题出现的可能性。
while(true)
{
if(tick>0)
{
//Thread.currentThread():获取当前线程对象。getName():获取线程名称。
System.out.println(Thread.currentThread().getName()+"....