线程

线程的状态:

1. 新建状态(New): 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。

2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。

进入就绪状态有3种方式:
1)CPU调度给优先级更高的thread,原先的thread进入等待状态
2)阻塞的thread获得资源或者信号,进入等待状态(等待当前thread结束后,便能执行)
3)时间片轮转的情况下,如果时间片到了,也将进入等待状态。

3. 运行状态(Running): 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。

4. 阻塞状态(Blocked): 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

  • (01) 等待阻塞 -- 通过调用线程的wait()方法,让线程等待某工作的完成。
  • (02) 同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
  • (03) 其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5. WAITING:由以下三种情况触发

1. Object.wait() 没有设置timeout(区别于 Object.wait(long timeout))
2. thread.join() 没有设置timeout (区别于 thread.join(long timeout))
3. LockSupport.park

6. TIMED_WAITING:由以下五种情况:

1. 调用Thread.sleep
2. Object.wait(long timeout) (这里区别于Object.wait(),有超时时间)
3. thread.join(long) (这里区别于Thread.join(),有超时时间)
4. LockSupport.parkNanos
5. LockSupport.parkUntil

7. 死亡状态(Dead): 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

 

线程的三种模式:
1)单线程
2)单元线程:有多个线程,所有线程都在主应用程序(进程)内存中各自的子段范围内运行。在.Net之前,Visual Basic只能创建单元线程应用程序。
3)自由线程:多个线程同时调用相同的方法和组件,即共享代码段
 
线程的同步和异步:
例:设计4个线程,其中两个线程每次对j增加1,另外两个线程每次对j减少1。循环100次。
public class ThreadTest1{
    private int j;
    public static void main(String args[]){ //main函数
        ThreadTest1 tt = new ThreadTest1(); //得到Main类的实例,才能创建线程(因为线程类是内部类)
        Inc inc = tt.new Inc(); //得到线程类的实例
        Dec dec = tt.new Dec();
        for(int i = 0; i < 2; i++){
            Thread t = new Tread(inc); //创建线程
            t.start(); //开启线程
            Thread t = new Tread(dec);
            t.start();
        }
    }
    private synchronized void inc(){//j是临界资源,不允许多个线程同时操作j,所以需要同步执行
        j++;
        System.out.println(Thread.currentThread().getName()+"-inc:" + j);
    }
    private synchronized void dec(){
        j--;
        System.out.println(Thread.currentThread().getName()+"-dec:" + j);
    }
    class Inc implements Runnable{ //线程类
        public void run(){
            for(int i = 0; i <100; i++){
                inc();
            }
        }
    }
    class Dec implements Runnable{
        public void run(){
            for(int i = 0; i <100; i++){
                dec();
            }
        }
    }
}
 
线程间的通信
1. 使用全局变量。
在主线程中定一个全局变量,然后让辅助线程不断地监测该全局变量,当全局变量的值是设定的终止标志值时,停止辅助线程。全局变量必须声明为volatile型变量。
例:
volatile bool bThreadStop = false;
AfxBeginThread(recvThreadProc, NULL, THREAD_PRIORITY_NORMAL);
UINT RecvThreadProc(LPVOID param)
{
    AfxMessageBox("线程已经启动");
    while(!bThreadStop)
    {
        //do something
    }
    ::AfxMessageBox("线程已经停止");
    return 0;
}
在需要停止辅助线程时,只要: bThreadStop = true;
2. 使用自定义的消息。
const WM_USERMSG = WM_USER+100;

//以下代码为辅助线程
CString strTemp, strIp;
strIp = "192.168.0.1";
strTemp.Format("对应IP地址为%s", PCSTR(strIp));
//将字符串指针传回到主线程,如果用::PostMessage会报错
::SendMessage(hwnd, WM_USERMSG,0,(LPARAM)(PCSTR(strTemp)));
 
LRESULT CScanDlg::WindowProc(UINT message, WPARAM wParam PARAM Param)
{
    CString strTemp;
    CString strThread;
    _tagThread *pThread;
    switch(message)
    {
    case WM_SCAN:
        strTemp = LPCSTR(lParam);
        MessageBox(strTemp);
        break;
    case WM_SCANOVER: 
        pThread = (_tagThread*) wParam;
        session.Lock();
        pThread->nThreadFlag = 3;
        pThread->pHost = &host[nCurrent];
        pThread->strMsg="";
        nThreadCount++;
        break;
    }
    return CDialog::WindowProc(message, wParam lParam);
}

3.使用事件

一个事件对象可以处于两种状态:信号态和非信号态。
#incude <afxmt.h>
//创建事件对象
CEvent g_eventStart; //启动事件
CEvent g_eventStop; //停止事件
//使信号处于信号态
g_event.SetEvent();
 
UINT ThreadProc(PVOID pParam)
{
    volatile int nTemp,g_nCount;
    ::WaitForSingleObject(g_eventStart,INFINITE);
    AfxMessageBox("Thread Start");
    for(g_nCount=0;g_nCount<100;g_nCount++)
    {
        for(nTemp=0;g_nCount<100;nTemp++)
        {
           if(::WaitForSingleObject(g_eventKill,0)==WAIT_OBJECT_0)
           break;
         }
     }
     return 0;
} 

 

posted on 2015-07-01 16:32  joannae  阅读(202)  评论(0编辑  收藏  举报

导航