简单说一下 程序、进程、线程
进程:当一个程序“跑” 起来的时候就是一个进程,即一个正在执行的程序,可以理解为:进程是一个”活“的程序。
线程:在程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身。
多线程:在一个程序中,可以同时运行多个执行单位(程序块)。 多线程可以让不同的程序块一起运行,可以让程序运行更流畅,达到多任务处理的目的。
如何创建线程呢?
多线程的创建方式:
方式一:继承Thread创建线程
public class Hello { public static void main(String[] args) { // 创建线程对象 TestThread t1=new TestThread("threadA", 600); TestThread t2=new TestThread("threadB", 7000); TestThread t3=new TestThread("threadc", 900); //启动线程 t1.start(); t2.start(); t3.start(); } } class TestThread extends Thread { private String threadName; private int ms; public TestThread(String threadName,int ms) { this.threadName=threadName; this.ms=ms; } @Override public void run() { //重写run()方法 super.run(); try { sleep(ms); // } catch (Exception e) { //捕获异常 System.out.println("the thread is error!"); } System.out.println("the thread name is:"+threadName+",sleep:"+ms+"毫秒"); } }
输出结果:
the thread name is:threadB,sleep:700毫秒
the thread name is:threadc,sleep:900毫秒
the thread name is:threadA,sleep:3000毫秒
为什么不是按threadA、threadB、threadC顺序打印?其实这个就是线程的奥妙所在之处:在main()中,创建了t1、t2、t3三个线程并传入参数,运行到t1.start();启动线程并自动调用run()方法,在run()方法中,sleep(3000)这个方法使得t1线程暂时停止运行3000毫秒,之后线程才可以恢复运行。在t1线程休眠的时间里,把执行权主动地交给了t2、t3,而不是等待t1恢复运行后再让t2、t3运行。
方式二:实现Runnable接口创建线程
public class Hello
{
public static void main(String[] args)
{
// 创建线程对象
RunnableTest r1=new RunnableTest();
r1.rOK(r1);
System.out.println(r1.print());
}
}
/**
*
*来一个父类
*/
class RunnableFat
{
public String print()
{
return "i am father class of Runnable ";
}
}
class RunnableTest extends RunnableFat implements Runnable
{
Thread t2=null; //
public void rOK(RunnableTest rt) //创建一个方法
{
Thread t1=new Thread(rt,"firsr thread");
System.out.println("正在运行的是:"+t1);
t2=new Thread(rt,"second thread");
System.out.println("创建 second thread");
System.out.println("first thread 开始休眠");
t2.start(); //启动t2线程
try
{
t1.sleep(500); //t1线程休眠500毫秒
}
catch (Exception e)
{
System.out.println("first thread 错误");
}
System.out.println("first thread 恢复");
}
@Override
public void run() //重写Runnable接口的run()方法
{
//
for(int i=0;i<900;i+=100)
{
System.out.println("second thread 休眠时间:"+i);
try
{
t2.sleep(i);
}
catch (InterruptedException e)
{
System.out.println("second thread 错误");
}
}
System.out.println("second thread 结束 ");
}
}
输出结果:
正在运行的是:Thread[firsr thread,5,main]
创建 second thread
first thread 开始休眠
second thread 休眠时间:0
second thread 休眠时间:100
second thread 休眠时间:200
second thread 休眠时间:300
first thread 恢复
i am father class of Runnable
second thread 休眠时间:400
second thread 休眠时间:500
second thread 休眠时间:600
second thread 休眠时间:700
second thread 休眠时间:800
second thread 结束
两种方式的区别是什么?
实现Runnable接口除了拥有和继承Thread类一样的功能外,还具有以下功能:
a) 适合多个相同程序代码的线程处理同一资源的情况,可以把线程同程序中的数据有效分离,较好的体现了OOP设计思想。
b) 可以避免由于java单继承特性带来的局限。因为在java中规定了一个类只能有一个父类,不能同时有两个父类,所以只能实现Runnable接口了。 例如:class BB已经继承了class AA,假如要把BB类放入线程中去,那么就不能使用继承Thread的方式。
c) 增强了代码的健壮性。代码可以被多个线程共同访问,代码与数据是独立的。多个线程可以操作相同的数据,与它们的代码无关。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口的实例。
是不是很简单?领童鞋们入门而已:)关键靠自己!
stay hungry stay foolish