线程
1. 新建状态(New): 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。
2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。
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()方法,该线程结束生命周期。
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(); } } } }
volatile bool bThreadStop = false; AfxBeginThread(recvThreadProc, NULL, THREAD_PRIORITY_NORMAL); UINT RecvThreadProc(LPVOID param) { AfxMessageBox("线程已经启动"); while(!bThreadStop) { //do something } ::AfxMessageBox("线程已经停止"); return 0; }
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; }