1.进程和线程
2.多线程
3.创建多线程
4.调用run和调用start的区别
5.线程的默认名字
6.线程的四种状态
7.线程优先级
1.进程与线程
进程:正在 运行的程序。就是应用程序在内存中分配的空间
线程:是进程中负责程序执行的基本执行单元。一个进程中至少要有一个线程,如果一个进程拥有多个线程,则称为多线程。(线程也叫执行路径)
2.多线程
一个进程如果只有一个线程,那么他只能做完一个任务再做另一个任务,不同同时做多个任务,从main方法运行的线程叫主线程。而多线程就像是一个人的分身 一样,可以同时去做多个事情。
程序的执行运算由CPU完成,在某一时间中,其实就只有一个线程能在CPU中运行,但由于CPU会执行一个线程一段时间后,切换到另外一个线程,所以看起来像同时运行几个任务。就如电脑开5个浏览器,没问题,CPU应付得过来,但如果你开500个浏览器就会卡,因为太多线程在等待CPU处理,CPU处理不过来。
3.创建多线程
创建多线程有两种方法:
一,通过继承Thread类。
1.继承Thread类
2.覆盖run方法(自定义线程的任务代码都在run方法中,run方法必须用public修饰,且返回值为void。主线程的任务代码都在main方法中)
3.创建子类对象(就是创建线程对象)
4.调用Thread类中的start方法就会执行线程,并会自动调用run方法
演示代码:
class MyThread extends Thread //定义线程类
{
private String name;
MyThread(String name)
{
this.name = name;
}
public void run() //run方法必须用public修饰,返回值为void
{
show();
}
public void show()
{
for(int i=0;i<10;i++)
System.out.println(name+":"+i);
}
}
public class Main
{
public static void main(String[] args) {
MyThread t1 = new MyThread("Thread1"); //创建线程1
MyThread t2 = new MyThread("Thread2"); //创建线程2
t1.start(); //启动线程1
t2.start(); //启动线程2
for(int i=0;i<10;i++) //主线程
System.out.println("MainThread:"+i);
}
}
打印结果是:3条线程会不确定地打印信息。每次运行程序线程的打印顺序都不一样。因为CPU具体什么时候执行哪一条线程是不确定的。
二,通过实现Runnable接口
1.定义一个类实现 Runnable接口
2.覆盖Runnable接口中的run()方法
3.通过Thread类(官方的类)创建线程对象。在让实现了Runnable接口的对象作为Thread类的构造函数的参数进行传递。
4.调用Thread对象的start()方法开启线程
演示代码:
class MyThread implements Runnable //注意,这并不是一个线程,而是一个线程的任务。
{
public void run()
{
for(int i=0;i<10;i++)
{
System.out.println(Thread.currentThread().getName()+i);
}
}
}
public class Main
{
public static void main(String[] args) {
MyThread mt = new MyThread(); //创建一个线程任务对象
Thread t1 = new Thread(mt); //创建一个线程对象,并把线程任务传给线程对象(导入线程任务)
t1.start();
}
}
两种创建线程的方法对比:
1.后者(通过实现Runnable接口)有更好的解耦性,因为他把线程和线程任务分开来,一个任务可以由多个线程来完成。而前者(通过继承Thread类)则把线程和线程任务绑定在一起。
2.若有一个售票站,有100张票要卖出去,后者可以通过创建多个线程,再导入线程任务来达到多个线程共同完成一个任务。但前者如果创建多个线程,则每个线程都会有
100张票,这就不符合需求了。
3.后者具有多实现(接口),避免了前者只能单继承的局限性。所以一般创建线程都是用后者(通过实现Runnable接口)
4.调用run和调用start的区别
调用 run是不能开启线程的,调用start才可以开启线程并执行run。
如果调用了在主函数调用的是run而不是start,则主线程回去执行自定义线程的 run()方法。即无论哪个线程的任务都是主线程来做。
5.线程的默认名字
线程是有默认名字的,主线程的名字为main,而自定义线程则是“Thread-n”,n从0开始,如第一个自定义线程默认叫Thread-0,,第二个则叫 Thread-1
获取线程的名字:
System.out.println(Thread.currentThread().getName());
currentThread()是Thread类的静态函数,返回当前正在执行的线程的引用,getName()则是打印出线程的名字。
6.线程的四种状态
1.运行态
2.临时阻塞态
3.冻结态
4.消亡态
1.运行态:指的是该线程当前正被CPU执行。
2.临时阻塞态:指的是正在等待CPU执行他,正在排队中。
3.冻结态:指的是一个线程调用了sleep()来睡眠一段时间。或者调用wait()使线程一直冻结起来,不被CPU所执行。
4.消亡态:当线程中的 run()方法结束时,该线程就消亡了。
7.线程优先级
把一个线程设置成更好的优先级,相比优先级低的线程,可以让CPU有更高的几率调用优先级高的线程。
1.设置方式:
Thread t = new Thread(x);//创建一个线程t
t.setPriority(参数);//设置线程t的优先级
方法setPriority()的参数可以是数字(1~10),数字越大,优先级越高,也可以是以下宏:
MAX_PRIORITY :线程获得最高的优先级
MIN_PRIORITY : 线程获得最低的优先级
NORM_PRIORITY : 线程获得默认的优先级