Java多线程

王朝学院·作者佚名  2016-05-28
窄屏简体版  字體: 小  |  中  |  大  |  超大  

java多线程1、多线程概述当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。主要以下几个优点:

线程之间很容易实现共享内存创建线程代价较小Java语言内置多线程功能支持2、线程的创建和启动所有的线程对象都是Thread类或其子类的对象,每一个线程完成一定的任务。Java定义了两种创建线程的方法:方法一:继承Thread类创建线程类Ø 定义Thread的子类,并重写run方法

Ø 创建Thread子类的实例,即创建了线程对象

Ø 用线程对象的start方法来启动该线程

1 public class DemoThread extends Thread 2 { 3 PRivate int i; 4 String name; 5 public DemoThread(String name) 6 { 7 super(name); 8 } 9 public void run()10 {11 for(;i<100;i++)12 System.out.println(Thread.currentThread().getName()+"-------"+i);13 14 }15 public static void main(String[] args)16 {17 for(int i=0;i<100;i++)18 {19 System.out.println(Thread.currentThread().getName()+"-----------"+i);20 21 if(i==20)22 {23 new DemoThread("windows1").start();24 new DemoThread("windows2").start();25 }26 }27 }28 }

方法二:实现Runnable接口创建线程类Ø 定义Runnable接口的实现类,并重写该接口的run方法(该方法是该线程的线程执行体)

Ø 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Tread对象

1 public class DemoThread implements Runnable 2 { 3 private int i; 4 public void run() 5 { 6 for(;i<100;i++) 7 System.out.println(Thread.currentThread().getName()+"-------"+i); 8 9 }10 public static void main(String[] args)11 {12 for(int i=0;i<100;i++)13 {14 System.out.println(Thread.currentThread().getName()+"-----------"+i);15 16 if(i==20)17 {18 DemoThread t=new DemoThread();19 new Thread(t,"Windows1").start();20 new Thread(t,"Windows2").start();21 }22 }23 }24 }

两种方法比较:

采用实现Runnable接口方式的线程还可以继承其他类,而继承Tread类后不能再继承其他父类。实现Runnable接口方式的线程可以共享一个target对象,适合多个相同线程来处理同一份资源的情况若需要访问当前线程,实现Runnable接口方式只能使用Thread.currentThread()方法,而继承Thread可直接使用this即获取当前线程。3、线程的生命周期线程被创建并启动以后要经历五种状态,分别是新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)。新建:使用关键字new创建一个线程后,处于新建状态,此时仅由虚拟机为其分配内存并初始化成员变量,程序不会执行线程执行体。就绪:当线程对象调用start()方法后,该线程处于就绪状态,虚拟机为其创建调用栈和程序计数器,但是此时线程并没有运行,只是表示线程可以运行了。运行:当处于就绪状态的线程获得了CPU,开始执行run方法,则该线程处于运行状态。阻塞:当发生线程调用sleep方法、阻塞式IO方法、suspend方法、等待通知(notify),线程将近阻塞状态。阻塞状态在合适的时候会重新进入就绪状态。死亡:线程会以以下三种方式结束,然后就处于死亡状态,run方法执行完成、线程抛出未捕获的异常、直接跳跃stop方法结束进程。4、线程的控制isAlive():测试线程是否处于活动状态isDaemo():测试进程是否为守护进程join():等待该进程终止sleep():在指定的毫秒数内让正在执行的线程休眠,该线程不丢失任何监视器的所属权yield():暂停当前正在执行的线程对象,并执行其他线程,它是将线程转入就绪状态setPriority(int newPriority):更改线程的优先级5、线程的同步当两个或多个线程需要访问同一共享资源时,需要某种方式来确保资源在某一时刻只被一个线程使用,这个方式称为“同步“。

为了解决同步问题,java引入同步监视器,代码块格式如下:

synchronized (obj){}

Java还使用Synchronized关键字来修饰某个方法,此方法就无需显示指定同步监视器。同步锁:它具有与使用synchronized方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。 使用Lock对象的代码格式如下: 1 public class X 2 { 3 private final ReentrantLock lock=new ReentrantLock(); 4 public void m() 5 { 6 lock.lock();//加锁 7 try 8 { 9 //需要保证线程安全的代码10 }11 finally12 {13 lock.unlock();//释放锁14 }15 }16 }17

6、线程的通信Java为了避免轮询检测,通过wait()、notify()和notifyAll()方法实现进程内通信的机制。wait():告诉调用线程放弃监控器进入等待模式直到其他线程进入同一监控器并调用notify()方法。notify():唤醒在此同步器上等待的单个线程notifyAll():唤醒在此同步器上等待的所有线程7、线程池线程池在系统启动时就创建大量空闲的线程,程序将一个Runnable对象传给线程池,线程池就会启动一个线程来执行该对象的run方法,当run方法执行结束后该线程不会死亡,而是再次返回线程池中称为空闲状态的,等待执行下一个Runnable对象的run方法。使用线程池来执行线程任务的步骤如下:调用Executors类的静态工厂方法创建一个ExecutorService对象,该对象代表一个线程池。创建Runnable实现类或Callable实现类的实例,作为线程执行任务。调用ExecutorService对象的submit方法提交Runnable实例或Callable实例。当不想提交任何任务时调用ExecutorService对象的shutdown方法来关闭线程池。eg: 1 class TestThread implements Runnable 2 { 3 public void run() 4 { 5 for(int i=0;i<50;i++) 6 { 7 System.out.println(Thread.currentThread().getName()+"---"+i); 8 } 9 }10 }11 public class TestMain12 {13 14 public static void main(String[] args)15 {16 // TODO 自动生成的方法存根17 TestThread t=new TestThread();18 ExecutorService pool=Executors.newFixedThreadPool(6);19 pool.submit(new Thread(t));20 pool.submit(new Thread(t));21 pool.shutdown();22 }23 24 }

执行结果:

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航