1、概念:下面是摘自百度百科对线程的定义
——————————————————————————————————————
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。每一个程序都至少有一个线程,那就是程序本身。
线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为 多线程。——————————————————————————————————————
当然,对于线程的定义上面已经说得很全了,这里我们主要说说线程的创建方式和一些需要注意的问题
2、创建:
java5以前有两种创建线程的方式
方式一,采用Thread类来创建,也就是继承自Thread类,实现如下
public class MyThread extends Thread{ public MyThread() { } //重写覆盖父类的run方法 public void run() { try { for(int i=0;i<10;i++) { Thread.sleep(1000); System.out.println("run in my thread:"+i); } } catch (InterruptedException e) { e.printStackTrace(); } } }
class MyThread2 implements Runnable { @Override public void run() { try { for(int i=0;i<10;i++) { Thread.sleep(1000); System.out.println("run in my thread2:"+i); } } catch (InterruptedException e) { e.printStackTrace(); } } }
使用线程如下
public static void main(String[] args) { System.out.println("***************Thread*************"); MyThread t=new MyThread(); t.start(); System.out.println("run in main thread"); MyThread2 t2=new MyThread2(); Thread t3=new Thread(t2); t3.start(); }
ExecutorService pool=Executors.newFixedThreadPool(10); pool.execute(new Runnable(){ public void run() { System.out.println("executor"); } });
以上就是创建线程的三种方式了。接下来说一下线程中常见几个方法的作用和区别
1、stop()方法:停止当前线程的执行。一般反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在
2、suspend()方法,该方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
3、sleep()方法:该方法是线程类的方法,它的作用是使当前线程停止多少时间后再继续执行,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁
4、wait()方法:该方法是Object的方法,它的作用是对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法,调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。
下面用程序演示一下wait方法和sleep方法的区别
public class Thread1 implements Runnable { public void run() { synchronized(ThreadDriver.class) { //由于这里的Thread1和下面的Thread2内部run方法要用同一对象作为监视器, //我们这里不能用this,因为在Thread2里面的this和这个Thread1的this不是 //同一个对象。我们用ThreadDriver.class这个字节码对象,当前虚拟机里引用 //这个变量时,指向的都是同一个对象。 System.out.println("thread1 is running..."); System.out.println("thread1 is waiting..."); try { ThreadDriver.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread1 continue..."); System.out.println("thread1 is over!"); } } }
public class Thread2 implements Runnable { public void run() { synchronized(ThreadDriver.class) { System.out.println("thread2 is running..."); System.out.println("thread2 notify other thread can release wait status.."); //由于notify方法并不释放锁, 即使thread2调用下面的sleep方法休息 //了100毫秒,但thread1仍然不会执行,因为thread2没有释放锁,所以 //Thread1无法得不到锁。 ThreadDriver.class.notify(); System.out.println("thread2 is sleeping ten millisecond..."); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread2 continue"); System.out.println("thread2 is over"); } } }
public class ThreadDriver { /** * @param args */ public static void main(String[] args) { Thread t1=new Thread(new Thread1()); t1.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } Thread t2=new Thread(new Thread2()); t2.start(); } }
测试结果
thread1 is running... thread1 is waiting... thread2 is running... thread2 notify other thread can release wait status.. thread2 is sleeping ten millisecond... thread2 continue thread2 is over thread1 continue... thread1 is over!
我们这里将Thread2中的Thread.sleep(100)改成ThreadDriver.class.wait();然后在Thread1执行完后加入ThreadDriver.class.notify();,这时我们将得到如下结果
thread1 is running... thread1 is waiting... thread2 is running... thread2 notify other thread can release wait status.. thread2 is sleeping ten millisecond... thread1 continue... thread1 is over! thread2 continue thread2 is over
从这里可以充分看出wait会释放对象锁,而sleep不会
联合以上的代码对wait和sleep应该好理解些。
以上的说明和代码参考了网络上的一些内容,并融合自己的理解整理而成,谢谢提供这些内容的朋友