黑马程序员---Java 线程

来源:互联网 发布:win7组策略优化 编辑:程序博客网 时间:2024/06/07 00:30
-----------android培训java培训、java学习型技术博客、期待与您交流!------------
关于线程:
线程:线程可以理解为进程中的执行的一段程序片段。
进程:普通的解释就是,进程是程序的一次执行。
基本的线程机制:一个程序就是在进程中的一个单一的顺序控制流,而一个进程可以有多个并发执行的任务并且可以保证每个线程都好像有自己的CPU。
1.(1)Runnable接口:要想让某个任务可以多线程执行,可以实现Runnable接口并重写run()方法。任务的run()方法通常会写成一个某种形式的循环,使得任务一直运行下去直到不再需要。所以为了避免一直不结束要设置调出循环的条件,也可以选择直接从run()返回。通常,run()被写成无线循环的形式,这就意味着,除非有某个条件使得run()终止,否则他将会永远运行下去。
案例:

public class test05 implementsRunnable{

     protected int countDown = 10;

     private static int taskCount = 0;

     private final int id = taskCount++;

     public test05(){

          

     }

     public test05(int testCount){

           this.countDown =countDown;

     }

     public String status(){

           return "#" + id +"("+(countDown > 0 ?countDown :"Liftoff") +").";

     }

 

     @Override

     public void run() {

           // TODO Auto-generatedmethod stub

           while(countDown-- > 0){

                System.out.println(status());

                Thread.yield();

           }

     }

    

     public static void main(String[] args){

           test05t = new test05();

           t.run();

     }

    

 

}
**当从Runnable导出一个类时,它必须具有run()方法,但是这个方法并无特殊之处——他并不会产生任何内在的线程能力。要实现线程的行为必须显式的讲一个任务附着到线程上。
  
(2)Thread:也可以继承Thread类,并且重写Thread类的run()方法。Thread构造器只需要一个Runnable对象。调用Thread对象的start()方法为该线程执行必须的初始化操作,然后调用Runnable的run()方法,以便在这个新任务中启动该任务。
案例:

public class testLiftOff implements Runnable{

     protected int countDown = 10;

     private static int taskCount = 0;

     private final int id = taskCount++;

     public testLiftOff(){

          

     }

     public testLiftOff(int testCount){

           this.countDown =countDown;

     }

     public String status(){

           return "#" + id +"("+(countDown > 0 ?countDown :"Liftoff") +").";

     }

 

     @Override

     public void run() {

           // TODO Auto-generatedmethod stub

           while(countDown-- > 0){

                System.out.println(status());

                Thread.yield();

           }

     }

    

     public static void main(String[] args){

           Threadt = new Thread(new testLiftOff());

           t.start();

           System.out.println("Waiting fortestLiftOff...");

 

     }

 

     

}
从上面这个案例可以看出,尽管start()看起来是产生了一个队长期运行方法的调用,但是从输出中可以看出,start()迅速的返回了,因为Waiting for testLiftOff..."消息在倒计时完成之前就出现了。实际上,我们对testLiftOff.run()的方法调用,并且这个方法还没有完成,但是因为testLiftOff.run()是由不同的线程执行的,因此程序仍可执行main()线程中的其他操作(并不是只有main()线程可以启动其他的线程,所有的线程都可以启动另外一个线程)。因此,上面的案例中会同事运行两个方法,main()和testLiftOff.run()是线程中与其他线程“同时”执行的代码。我们可以很容易的添加更多的线程去驱动更多的任务。
 
 
2.使用Executor:
java.util.concurrent包中的迭代器(Executor)可以管理Thread对象,从而简化并发操作。Executor在客户端和任务执行之间提供了一个间接层,与客户端直接执行任务不同,这个中介对象将执行任务。Executor允许程序员管理异步任务的执行,而不需要显示的管理线程的生命周期。例如上面的案例我们可以进行如下的修改:
案例:

importjava.util.concurrent.ExecutorService;

importjava.util.concurrent.Executors;

 

public class testLiftOff implements Runnable{

     protected int countDown = 10;

     private static int taskCount = 0;

     private final int id = taskCount++;

     public testLiftOff(){

          

     }

     public testLiftOff(int testCount){

           this.countDown =countDown;

     }

     public String status(){

           return "#" + id +"("+(countDown > 0 ?countDown :"Liftoff") +").";

     }

 

     @Override

     public void run() {

           // TODO Auto-generatedmethod stub

           while(countDown-- > 0){

                System.out.println(status());

                Thread.yield();

           }

     }

    

     public static void main(String[] args){

           ExecutorServicees = Executors.newCachedThreadPool();

           for(int i=0;i<5;i++){

                es.execute(new testLiftOff());

           }

           es.shutdown();

 

     }

 

    

 

}

**需要说明的是,这里需要导包。

对shutdown()方法的调用可以防止新任务被提交给这个Executor,当前线程将继续运行在shutdown()被调用之前提交的所有任务。

 

 

3.从任务中产生返回值

Runnable是执行工作的独立任务,但是他不返回任何值。如果想要在任务完成时返回一个值,可以实现Callable接口而不是Runnable接口。Callable是一个具有类型参数的泛型,它的类型参数表示的是从方法call()中返回的值,并且使用ExecutorService.submit()方法调用它。

 

 

4.休眠

影响任务行为的一种简单方法是调用sleep(),这将是任务中止执行,例如我们把上面的testLiftOff类中,要是把对yield()的调用换成sleep(),将得到不同的结果。对sleep()的调用可以抛出InterruptedException异常,而且它需要在run()中捕捉。因为一场不能跨线程传播回main(),所以必须在本地处理所有在任务内部产生的异常。

 

 

5.优先级

线程的优先级将线程的重要度传递给了调度器。尽管CPU处理现有线程集的顺序是不确定的,但是调度器将倾向于让优先权最高的线程先执行。然而这并不是意味着优先权较低的线程得不到执行,优先权是不会导致死锁的,他只是让优先权底的线程执行的频率也相对低而已。可以用setPriority()来设置优先级,并用getPriority()方法获得一个线程的优先级。

0 0
原创粉丝点击