java线程(一)

1.现在编程当中很多情况都必须要使用线程来完成指定的任务。
什么是线程呢?
2.有时候总有些人会把线程和进程的概念弄混,这里就简单说一下他们的区别:
  • 每个进程都有独立的代码和数据空间,进程间的切换开销大
  • 同一进程内的多个线程共享相同的代码和数据空间,每个线程有独立的运行栈和程序计数器,线程间的切换开销小
  • 程序需要同时执行两个或多个任务
  • 程序需要实现一些需要等待的任务时,如用户输入,文件读写操作,网络操作
  • 需要一些和后台一些的程序
3.为什么需要多线程呢?
  • 提高应用程序相应
  • 提高计算机系统CPU的利用率
  • 改善程序结构
4.线程分类:
  (1)  用户线程   (2)守护线程
    在代码用守护线程只要执行thread.setDaemon(true);就可以成为该线程的守护线程
5.创建线程的方法(两种):
    1)通过实现Runnable接口来。
        class MyRunnable implements Runnable{
            public void run(){
            //线程要执行的代码
        }            
 
    }
    2)通过继承Thread类:
        class MyThread extends Thread{
        @voidride
        public void run(){
        //线程要执行的代码
        }
    }    
    
6.线程时间片:
    在PC的CPU当中给每个线程分配得有时间片,线程之间去抢夺这个时间片来进行自己相应的线程处理。有可能你时间片用完了,但代码并未执行完,
并且下一个时间片被其他线程抢夺去了,那你只有等当前线程执行完时间片后,在去抢夺,才可能执行完,自己线程当中的代码。
所以有时候对线程进行操作,多线程执行的是同一段代码,可能得到的结果是不一样的,就是因为他们对CPU的时间片,抢夺造成的结果
7.线程的生命周期
    一般是有5个状态:创建-就绪-运行-阻塞-终止
    官方是分为6个状态的:
  • NEW:至今尚未启动的线程处于这种状态.  也就是线程执行方法start()后,
  • RUNNABLE:正在Java虚拟机中执行的线程处于这种状态
  • BLOCKED:受阻塞并等待某个监视器锁的线程处于这种状态 
  • WAITING:无限期的等待另一个线程执行某个特定操作的线程处于这种状态
  • TIMED_WAITING:等待另一个线程状态来执行取决于指定等待时间的操作的线程的状态 
  • TERMINATED:已退出的线程处于这种状态
在网上看到一张总结的很好的图片(将个状态对应的方法也列出来了):
   
8.下面用具体代码来说明java线程:
    8.1 线程睡眠:
        通过调用线程的sleep() 方法来使线程进入随眠状态 ,睡眠指定时间后,线程会接着运行的
                  
 1 public class ThreadTest {
 2 
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         System.out.println("主线程开始");
 8         System.out.println("线程一准备");
 9         NormalRunnable target = new NormalRunnable();
10         Thread thread1 = new Thread(target);
11         thread1.start();
12         System.out.println("线程二准备");
13         SleepRunnable runnable = new SleepRunnable();
14         Thread thread2 = new Thread(runnable);
15         thread2.start();
16         
17     }
18 
19     public static class NormalRunnable implements Runnable {
20 
21         @Override
22         public void run() {
23 
24             for (int i = 0; i < 50; i++) {
25                 System.out.println(Thread.currentThread().getName() + ":" + i);
26             }
27 
28         }
29 
30     }
31 
32     public static class SleepRunnable implements Runnable {
33 
34         @Override
35         public void run() {
36             for (int i = 0; i < 50; i++) {
37                 System.out.println(Thread.currentThread().getName() + ":" + i);
38             }
39 
40         }
41 
42     }
43 
44 }
   运行后的结果是:
   
其实当两个线程一起去抢夺CPU的时间片的,Thead-0抢到后就执行run中的代码,其实在run循环还未完成的时候时间片已经用完,Thread-1 就获取到了时间片,然而Thread-1的
run方法中线程要睡眠500毫秒,无奈让出时间片,Thread-0获取到时间片就继续执行未循环完的代码。如将SleepRunnable 中 Thread.sleep(500);去掉后,Thread-0 和Thread-1
就想公平竞争了,得到的结果可能是Thread-0和Thread-1相互交叉的了。
 为了证明这点,将Thread.sleep(500);去掉后运行后的结果是:
   
若你运行的循环次数可以改大一点,我改成50的就可以看到明显的结果
    Tread-1:49后是Thread-0:11 这说明前面Thread-0执行到了12的。所以上面所说的得到的证明
 8.2 线程让步:
    Thread.yield() 方法会展厅当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程
 1 public class ThreadYield {
 2 
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7 
 8         System.out.println(Thread.currentThread().getName());
 9         Thread thread1 = new Thread(new YieldThread());
10         thread1.start();
11         Thread thread2 = new Thread(new YieldThread());
12         thread2.start();
13     }
14 
15     public static class YieldThread implements Runnable {
16 
17         @Override
18         public void run() {
19 
20             for (int i = 0; i < 100; i++) {
21 
22                 System.out.println(Thread.currentThread().getName() + ":" + i);
23 
24                 if (i % 10 == 0) {
25                     Thread.yield();
26                 }
27 
28             }
29 
30         }
31 
32     }
33 
34 }
运行后的结果是:
从代码的意思就是线程执行循环的时候若能被10整除就会暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程.其实在让出时间片的线程竞争时间片中也包含让出时间片的线程。
所以在执行10个后可能还是执行该线程的10个.(你运行后的结果可能和我不一样,想看到更详细的运行结果可以将循环次数增加)
8.3线程加入
    有时候需要线程间,接力完成任务,这就需要调用线程类的join()方法,join() 方法可以是两个线程交叉完成任务的过程变成顺序完成任务
    
 1 public class ThreadJoin {
 2 
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         System.out.println("在主线线程当中顺序执行子线程");
 8         Thread thread1 = new Thread(new JoinRunnable());
 9         thread1.start();
10         for (int j = 0; j <5; j++) {
11             System.out.println(Thread.currentThread().getName() + ":" + j);
12             if (j == 2) {
13                 try {
14                     thread1.join();
15                 } catch (InterruptedException e) {
16                     e.printStackTrace();
17                 }
18             }
19         }
20 
21     }
22 
23     public static class JoinRunnable implements Runnable {
24 
25         @Override
26         public void run() {
27 
28             for (int i = 0; i <= 3; i++)
29                 try {
30                     System.out.println(Thread.currentThread().getName() + ":"
31                             + i);
32                     Thread.sleep(10);
33 
34                 } catch (Exception e) {
35                     e.printStackTrace();
36                 }
37 
38         }
39 
40     }
41     
42 
43 }
若还想再子线程当中顺序执行某个线程,只需要在要执行的线程中睡眠时间比自己的母线程多一点就可以了
posted @ 2015-06-08 23:29  perfect亮  阅读(194)  评论(0)    收藏  举报