线程基础

来源:互联网 发布:js事件代理和事件委托 编辑:程序博客网 时间:2024/05/18 13:09

首先我们来讲一下这个什么是线程,以及线程与进程之间的关系!

首先在系统中启动一个程序时我们都是为这个程序创建一个独立的进程,这样我们可以系统进程监视器中看到。还有我们必须明白dos的单任务的系统,如果一但中病毒那么dos系统就会死掉,但是在多任务系统中,一个程序中了病毒的话只有这个程序的进程会卡死,对其他的程序进程没有影响,就好比我们的windows系统一样。下面我们来引出这个线程。

线程就是在进程基础上的进一步划分,就好比在分钟上进一步划分的话就是秒。现在应该对线程有了初步的了解了!进程死掉,线程一定死掉,线程死掉,进程不一定死掉!进程是一个程序完整的执行过程!它经历了程序从加载,执行,到执行完毕的全过程!这个过程也是进程从产生,发展,到消亡的全过程。线程只是其中的一段执行过程。多线程是实现并发控制的基本技术手段。对于所有的线程来说系统资源都是共享的,所以他们都去抢占cpu的资源。虽然线程实现了系统的并发控制,及在一个时间段内程序是并行运行的,但是在一个时间点上,只有一个程序在执行。下面我们来看看线程的具体实现。

1 java实现多线程有两种方式,继承Thread 或者是实现Runnable接口!

Thread类和runnable接口都是在java.lang这个包中,所以我们不用导入就可以使用!

只要一个类继承了Thread类那么这个类就是一个线程操作类了,就可以 进行线程操作了!但是要注意一下几点,首先这个线程类必须重写父类的run方法,这个方法是没有返回值和参数列表的!是线程类的主体!

下面我们通过实际的代码来说明:

首先必须明确一点我们必须在线程中覆写run方法,还有就是我们在通过线程对象调用的时候我们要使用start方法,而不是直接调用run方法,这里的start方法最后调用的也是run方法。

线程Thread01这个类的代码如下:

package com.pzhu.www.thread;public class Thread01 extends Thread {private String name;public Thread01(String name) {this.name = name;}public Thread01() {}public void run() {for (int i = 0; i < 20; i++) {System.out.println("线程" + name + "   " + i);}}}

下面这个是测试类:

package com.pzhu.www.thread;public class Test01 {public static void main(String[] args) {Thread01 a = new Thread01("A");Thread01 b = new Thread01("B");a.start();b.start();}}


结果是一会A线程一会B线程!这里不多说!

但是有一点必须说明一下:其实我们Thread类的start方法通过native关键字调用了操作系统的底层函数来实现对cpu的抢占以及排队等等操作!最后我们的一个线程只能调用一次,如果多次调用的话就会抛出java.lang.IllegalThreadStateException异常!

2 通过实现Runnable接口

实现Runnable接口的代码如下:

package com.pzhu.www.thread;public class Runnable01 implements Runnable {private String name;public Runnable01() {}public Runnable01(String name) {this.name = name;}public void run() {for (int i = 0; i < 20; i++) {System.out.println("线程" + name + "  " + i);}}}

下面是测试代码:

package com.pzhu.www.thread;public class RunnableTest01 {public static void main(String[] args) {Runnable01 runnable = new Runnable01("A");Runnable01 runnable01 = new Runnable01("B");Thread thread = new Thread(runnable);Thread thread01 = new Thread(runnable01);thread.start();thread01.start();}}

3 来看看Runnable接口和Thread类的关系:

其实我们看文档就会发现,其实Thread类也实现了Runnable接口的,但是我们在通过Runnable接口来实现多线程时,我们也创建了Thread类,而且我们通过Thread类的构造方法传进了Runnable 的实现类,然后通过Thread类的Start方法来实现多线程了!而且必须创建Thread类才能实现!这里的Thread类和Runnable接口之间的关系有点像代理模式!


下面我们来看看这两者之间的关系:首先Thread类无法实现资源的共享,而Runnable接口可以实现资源的共享!

下面来举例说明:


package com.pzhu.www.thread;public class Thread01 extends Thread {private int k = 5;public void run() {for (int i = 0; i < 5; i++) {System.out.println("卖出第" + k + "几张票!");k--;}}}


测试类如下:
package com.pzhu.www.thread;public class ThreadTest01 {public static void main(String[] args) {Thread01 a = new Thread01();Thread01 b = new Thread01();a.start();b.start();}}

最后可以看到a线程和b线程各自执行了五次!


下面我们来看看这个runnable接口时怎样实现资源共享的!

代码如下:

package com.pzhu.www.thread;public class Runnable01 implements Runnable {private int k = 5;public Runnable01() {}public void run() {for (int i = 0; i < 5; i++) {if (k > 0) {System.out.println("卖出第" + k + "几张票!");k--;}}}}


下面是测试类的代码:

package com.pzhu.www.thread;public class RunnableTest01 {public static void main(String[] args) {Runnable01 runnable = new Runnable01();Thread thread = new Thread(runnable);Thread thread01 = new Thread(runnable);thread.start();thread01.start();}}

最后可以看到 这里虽然启动了两个线程,但是最后我们只看到了最后总共输出了五次!这就实现了资源的共享!

那是怎样实现的呢??

首先在ThreadTest01这个类中我们创建了两个Thread01这个类,所以在内存中我们有两个K ,两个对象都执行各自的run方法来访问各自的k所以就没有实现资源共享。

而runnable接口的实现类不一样,我们来看看这个RunnableTest01这个类,我只创建了一个线程操作类Runnable01的对象,但是创建了两个线程,两个现场那个传递的进入都是这个对象,所以我们操作的这个对象的k成员变量是同一个成员变量!所以实现了资源的共享!!


线程也是有生命周期的!

首先创建一个线程对象: Thread01  t = new  Thread01();

线程就绪状态: 调用start方法

线程执行状态:调用run方法

线程阻塞状态:线程中止或者将资源让给其他的程序使用

线程死亡:线程的退出!


最后我们在实践中首选Runnable接口!



欢迎评论!!!