程序是一段静态的代码。
进程是程序的一次动态执行过程,程序执行的过程对应了进程从产生、发展至消亡的过程。
线程是比进程更小的执行单位。一个进程在执行过程中可以产生多个线程。
每个进程都有一段专用的内存区域。与此不同的是,线程间可以共享相同的内存单元(包括代码和数据)。
Java程序总是从主类的main方法开始执行。JVM加载代码,发现main方法后,会启动一个线程,这个线程就是主线程,负责执行main方法。那么,在main方法的执行中在创建的线程,就称为程序的其他线程。
Java有两种方法实现多线程,继承Thread类或者实现Runnable接口。
Thread类和Runnable接口中都有一个run()方法。Thread类中的run()方法是空方法,没有具体内容。子类必须重写父类的run()方法。
两个例子,创建3个线程对5张车票进行售卖:
继承Thread类:优点:继承Thread类的子类对象就是线程对象 缺点:不适合多继承。java中,类不能多继承,却可以实现多个接口。
class MyThread extends Thread
{
private int ticket = 5;
public void run()
{
for(int i = 0; i < 100; i ++ )
{
if(ticket > 0)
{
System.out.println(Thread.currentThread().getName() + "刚刚卖了第:"+ ticket-- +"张票");
}
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread a = new MyThread();
MyThread b = new MyThread();
MyThread c = new MyThread();
a.start();
b.start();
c.start();
}
}
输出结果:
Thread-1刚刚卖了第:5张票
Thread-1刚刚卖了第:4张票
Thread-1刚刚卖了第:3张票
Thread-1刚刚卖了第:2张票
Thread-1刚刚卖了第:1张票
Thread-0刚刚卖了第:5张票
Thread-0刚刚卖了第:4张票
Thread-0刚刚卖了第:3张票
Thread-0刚刚卖了第:2张票
Thread-0刚刚卖了第:1张票
Thread-2刚刚卖了第:5张票
Thread-2刚刚卖了第:4张票
Thread-2刚刚卖了第:3张票
Thread-2刚刚卖了第:2张票
Thread-2刚刚卖了第:1张票
然而,问题来了,有的票会被重复卖掉。一般来说,还是一个目标对象创建多个线程比较好。而不是多个目标对象,每个目标对象创建一个线程。
class MyThread extends Thread
{
private int ticket = 5;
public void run()
{
for(int i = 0; i < 100; i ++ )
{
if(ticket > 0)
{
System.out.println(Thread.currentThread().getName() + "刚刚卖了第:"+ ticket-- +"张票");
}
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread a = new MyThread(); //创建一个目标对象
Thread aa = new Thread(a); //创建线程aa
Thread bb = new Thread(a); //创建线程bb
Thread cc = new Thread(a); //创建线程cc
aa.start();
bb.start();
cc.start();
}
}
输出结果:
Thread-2刚刚卖了第:4张票
Thread-2刚刚卖了第:3张票
Thread-2刚刚卖了第:2张票
Thread-2刚刚卖了第:1张票
Thread-1刚刚卖了第:5张票
实现Runnable接口:
class MyRunnable implements Runnable
{
private int ticket = 5;
public void run()
{
for(int i = 0; i < 100; i ++)
{
if(ticket > 0)
System.out.println(Thread.currentThread().getName()+"刚刚卖出了第" + ticket-- +"张票");
}
}
}
public class RunnableDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyRunnable a = new MyRunnable();
new Thread(a).start();
new Thread(a).start();
new Thread(a).start();
}
}
输出结果:
Thread-0刚刚卖出了第5张票
Thread-0刚刚卖出了第4张票
Thread-1刚刚卖出了第3张票
Thread-1刚刚卖出了第2张票
Thread-1刚刚卖出了第1张票