进程:
是一个正在执行中的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
线程:
就是进程中的一个独立的控制单元。线程在控制着进程的执行。
一个进程中至少有一个线程。
Java VM启动的时候会有一个进程java.exe
该进程中至少一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称为主线程。
扩展:
其实更细节说明JVM,JVM启动不止一个线程,还有负责
垃圾回收的线程。
1、如何在自定义的代码中,自定义一个线程呢?
通过对API的查找,JAVA已经提供了对线程这类事物的描述。就Thread类。
创建线程的第一种方式:继承Thread类.
步骤:
1>定义类继承Thread.
2>复写Thread类中的run方法
目的:将自定义的代码存储在run方法中。让线程运行。
3>调用线程的start方法,该方法两个作用:启动线程,调用run方法。
class Demo extends Thread
{
public void run()
{
for(int x= 0;x<10;x++)
System.out.println("demo run");
}
}
class ThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo();//创建好一个线程,并没执行
d.start();
for(int x =0;x<10;x++)
System.out.println("Hello World!---"+x);
}
}
发现运行结果每次都不同。因为多个线程获取CPU的执行权,cpu执行到谁,谁就运行。
明确一点,在某一时刻,只能有一个程序在运行。(多核除外)
cpu在做着快速的切换,以达到看上去是同时运行的效果。
我们可以形象把多线程的运行行为看成是互相抢夺cpu的执行权。
这就是多线程的一个特性:随机性,谁抢到谁执行,至于执行多长时间,cpu说的算。
假如说我们不调用start方法,而是直接调用run方法:
class Demo extends Thread
{
public void run()
{
for(int x= 0;x<10;x++)
System.out.println("demo run");
}
}
class ThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo();//创建好一个线程,并没执行
//d.start();
d.run();
for(int x =0;x<10;x++)
System.out.println("Hello World!---"+x);
}
}
结果无论运行多少次都是一样的。为什么呢?因为没有调用start,线程虽然创建了,可是线程根本就没有开启,就相当于在主线程中执行的,也就是和普通的方法调用没有区别。
线程运行的状态:
线程有自己默认的名称:
Thread-编号 该编号从0开始
static Thread currentThread():获取当前线程对象
getName():获取线程名称
设置线程名称:setName或者构造函数
例子:简单的卖票程序,多个窗口同时卖票
class Ticket extends Thread
{
private int ticket = 20;
public void run()
{
while(true)
{
if(ticket>0)
{
System.out.println(Thread.currentThread().getName()+"---sale :"+ticket--);
}
}
}
}
class TicketDemo
{
public static void main(String[] args)
{
Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
Ticket t3 = new Ticket();
Ticket t4 = new Ticket();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
我们发现其实创建了四个线程,每个线程都有20张票。所以怎么才能让这四个线程共享这20张票呢?
有人肯定会想设置为静态变量不就行了吗?我们看看:
确实可以啊,不过我们不提倡使用静态变量。因为占用时间太长。那到底还有没有别的方法呢?有人想,这不简单吗?让一个线程执行多次不就行了吗?
class TicketDemo
{
public static void main(String[] args)
{
Ticket t1 = new Ticket();
t1.start();
t1.start();
t1.start();
t1.start();
}
}
一个线程开启了,再开启几次有用吗??没用的。那具体怎么解决呢?那就引出来了Runnable接口。
请见下篇。