• 浅谈线程


         在说线程之前,有必要说下进程,进程是指程序的一次动态执行过程,或者说进程是正在执行中的程序,其占用特定的地址空间。现代的操作系统,如Windows和UNIX系统,都支持多任务处理,即将CPU的计算时间动态地划分给多个进程,这样操作系统可以同时运行多个进程,这些进程是相互隔离的。独立运行的程序。

         相对于进程,线程是进程中一段连续的控制流程或是一段执行路径。它不能独立存在,必须存在于某个进程中。一个进程可以拥有多个线程,这些线程可以共享进程中内存单元,可以访问相同的变量和对象,以实现线程间通信,数据交换和同步操作等功能。

        在java语言中线程的创建有两种方式:1.定义一个Thread类的子类,并在该类中重写run()方法,该run方法是线程执行的起点;2.定义一个实现Runnable接口的类,并在该类中定义Runnable接口的run()方法,还需要引用Thread类的构造方法,才能真正成为线程对象。

    线程的状态:     一个线程对象从创建,启动,运行,终止,直到线程对象被java虚拟机所释放,其生命周期会处于以下四种状态“运行”,“暂停”,“同步”,“挂起”。一个线程对象调用了start()方法后,并不意味着该线程立刻被java虚拟机执行,该线程还需要通过java虚拟机 的调度等待分配给它的CPU计算资源。只有当线程得到了CPU计算资源,它才能真正执行run()方法中所包含的语言,这也是启动是引用start方法,而不是直接引run()方法的原因。

    终止:

         当线程对象run()方法中所包含的语句执行完毕,则该线程对象作为一独立的执行逻辑即终止,它就不能再运行了。但该线程对象仍然存在,对此可采用isAlive()方法来判断线程是正在执行当中,还是已经终止。

    暂停:

         暂停是指让正在执行的线程暂时停止运行,并在暂停一段时间后,再恢复运行。

    sleep()方法是让线程“睡眠”即停止运行 所指定的一段时间,在睡眠结束后,线程立即恢复执行。

    join()方法的作用是使当前运行的线程停下来等待,直至所引用join()方法的另一个线程终止。

    同步:

         当多个线程对同一数据或对象进行读/写操作时,就需要协调它们对数据的访问,使它们得到数据的一致视图,否则它们之间会互相干扰,在程序中产生不可预期的结果。这种协调机制称为线程的同步。

    下面这个列子阐明线程间是如何实现同步的:

     1 package com;
     2 
     3 import java.util.Date;
     4 
     5 public class Demo {
     6 
     7     /**
     8      * @param args
     9      */
    10     public static void main(String[] args) {
    11         // TODO Auto-generated method stub
    12         CubbyHole ch = new CubbyHole();
    13         Producer p = new Producer(ch);
    14         Consumer c = new Consumer(ch);
    15         p.start();
    16         c.start();
    17     }
    18 }
    19 
    20 class CubbyHole {
    21     
    22     private int content;
    23     private boolean available = false;
    24 
    25     public synchronized int get() {
    26 
    27         while (available == false) {
    28             try {
    29                 wait();
    30             } catch (InterruptedException e) {
    31                 System.out.println(e);
    32                 e.printStackTrace();
    33             }
    34         }
    35 
    36         available = false;
    37         notifyAll();
    38         return content;
    39     }
    40 
    41     public synchronized void put(int value) {
    42 
    43         while (available == true) {
    44             try {
    45                 wait();
    46             } catch (InterruptedException e) {
    47                 System.out.println(e);
    48                 e.printStackTrace();
    49             }
    50         }
    51         content = value;
    52         available = true;
    53         notify();
    54     }
    55 }
    56 
    57 class Producer extends Thread {
    58 
    59     private CubbyHole cubbyhole;
    60 
    61     public Producer(CubbyHole c) {
    62         cubbyhole = c;
    63     }
    64 
    65     public void run() {
    66         for (int i = 0; i < 10; i++) {
    67             cubbyhole.put(i);
    68             System.out.println("Producer " + "put:" + i + ":" + new Date());
    69             try {
    70                 Thread.sleep((int) Math.random() * 1000);
    71             } catch (InterruptedException e) {
    72                 System.out.println(e);
    73                 e.printStackTrace();
    74             }
    75         }
    76     }
    77 }
    78 
    79 class Consumer extends Thread {
    80 
    81     private CubbyHole cubbyhole;
    82 
    83     public Consumer(CubbyHole c) {
    84         cubbyhole = c;
    85     }
    86 
    87     public void run() {
    88         int value = 0;
    89         for (int i = 0; i < 10; i++) {
    90             value = cubbyhole.get();
    91             System.out
    92                     .println("Consumer " + " get:" + value + ":" + new Date());
    93 
    94         }
    95     }
    96 }

    执行结果:

    Producer put:0:Fri May 24 22:40:02 CST 2013
    Consumer  get:0:Fri May 24 22:40:02 CST 2013
    Consumer  get:1:Fri May 24 22:40:02 CST 2013
    Producer put:1:Fri May 24 22:40:02 CST 2013
    Consumer  get:2:Fri May 24 22:40:02 CST 2013
    Producer put:2:Fri May 24 22:40:02 CST 2013
    Producer put:3:Fri May 24 22:40:02 CST 2013
    Consumer  get:3:Fri May 24 22:40:02 CST 2013
    Consumer  get:4:Fri May 24 22:40:02 CST 2013
    Producer put:4:Fri May 24 22:40:02 CST 2013
    Consumer  get:5:Fri May 24 22:40:02 CST 2013
    Producer put:5:Fri May 24 22:40:02 CST 2013
    Producer put:6:Fri May 24 22:40:02 CST 2013
    Consumer  get:6:Fri May 24 22:40:02 CST 2013
    Producer put:7:Fri May 24 22:40:02 CST 2013
    Consumer  get:7:Fri May 24 22:40:02 CST 2013
    Producer put:8:Fri May 24 22:40:02 CST 2013
    Consumer  get:8:Fri May 24 22:40:02 CST 2013
    Producer put:9:Fri May 24 22:40:02 CST 2013
    Consumer  get:9:Fri May 24 22:40:02 CST 2013

    该实例主要描写了两个线程和一个共享对象间的操作。其中Producer线程是往共享对象CubbyHole中填数,而另一个Consumer线程则是从该共享对象中取数。

    线程同步是通过如下两个方面来共同作用而实现的:一是通过关键词 synchronized 给关键对象或数据加锁,这里的关键对象即为CubbyHole对象,;另一方面是利用wait()和notify()方法实现线程间相互等待和唤醒。

  • 相关阅读:
    VC++ error C2248: “CObject::CObject”: 无法访问 private 成员(在“CObject”类中声明)
    VC++ 在使用 CImage 的Draw 输入一个图像时,有时候会造成图像失真严重,解决的方法如下
    VC++ 中CDC与HDC的区别以及二者之间的转换
    BASE64编码和解码(VC源代码) 并 内存加载 CImage 图像
    VC 使用OnCtlColor函数来改变控件颜色(引用)
    VC++ 对话框程序响应键盘消息的处理方法的说明(非常重要)
    VC++ 迭代器 iterator, const_iterator, const iterator
    VC++ 解决在鼠标移动时,光标闪烁的问题。其实本质是 ON_SETCURSOR的用法
    SQL练习题-50道SQL练习题及答案与详细分析
    Windows Essentials Movie Maker 安装失败报错 ——问题解决
  • 原文地址:https://www.cnblogs.com/gexiaoshan/p/3098112.html
Copyright © 2020-2023  润新知