《電子技術應用》
您所在的位置:首頁 > 模擬設計 > 設計應用 > 利用iphone的多線程實現“售票系統”
利用iphone的多線程實現“售票系統”
摘要: 在這篇文章中,筆者就拿大多數Java教程中經典的“售票系統多線程”作為實際例子,在iphone中進行同樣的實現。
Abstract:
Key words :

  Java因為其本身支持多線程而給程序員帶來很多方便,其實在iphone開發中也支持多線程編程,并且一點也不比java麻煩。

  在這篇文章中,筆者就拿大多數Java教程中經典的“售票系統多線程”作為實際例子,在iphone中進行同樣的實現。

  下面是java版本的“售票系統多線程”代碼:

  package demo;

  public class SellTickets implements Runnable{

  private int tickets=100;

  public void run() {

  int count=0;

  while (true)

  {

  //上鎖

  synchronized(this){

  if (tickets》0){

  try {

  Thread.sleep(500);

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  count=100-tickets;

  System.out.println(“當前票數是:”+tickets+“售出”+count

  +“線程名:”+Thread.currentThread().getName());

  tickets--;

  }else{

  break;

  }

  }

  }

  }

  public static void main(String[] args) {

  SellTickets r=new SellTickets();

  Thread t1=new Thread(r,“t1”);

  t1.start();

  Thread t2=new Thread(r,“t2”);

  t2.start();

  Thread t3=new Thread(r,“t3”);

  t3.start();

  Thread t4=new Thread(r,“t4”);

  t4.start();

  }

  }

  以上java版本的代碼執行后控制臺輸出如下:

  當前票數是:100售出0線程名:t1

  當前票數是:99售出1線程名:t2

  當前票數是:98售出2線程名:t3

  當前票數是:97售出3線程名:t4

  當前票數是:96售出4線程名:t1

  當前票數是:95售出5線程名:t2

  當前票數是:94售出6線程名:t3

  當前票數是:93售出7線程名:t4

  當前票數是:92售出8線程名:t1

  當前票數是:91售出9線程名:t2

  當前票數是:90售出10線程名:t3

  當前票數是:89售出11線程名:t4

  當前票數是:88售出12線程名:t1

  當前票數是:87售出13線程名:t2

  當前票數是:86售出14線程名:t3

  當前票數是:85售出15線程名:t4

  當前票數是:84售出16線程名:t1

  當前票數是:83售出17線程名:t2

  當前票數是:82售出18線程名:t3

  當前票數是:81售出19線程名:t4

  當前票數是:80售出20線程名:t1

  當前票數是:79售出21線程名:t2

  當前票數是:78售出22線程名:t3

  當前票數是:77售出23線程名:t4

  當前票數是:76售出24線程名:t1

  當前票數是:75售出25線程名:t2

  當前票數是:74售出26線程名:t3

  當前票數是:73售出27線程名:t4

  ……

  可以在iphone中進行同樣的實現,Iphone的Frameworks/Foundation.framework框架支持多線程編程,接口定義在:

  /Xcode3.1.4/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSThread.h

  到相應的目錄下打開此文件,可以看到絕大多數java中的接口這里也都能找到相應的實現,如下:

  /* NSThread.h

  Copyright (c) 1994-2007, Apple Inc. All rights reserved.

  */

  #import 《Foundation/NSObject.h》

  #import 《Foundation/NSDate.h》

  @class NSArray, NSMutableDictionary, NSDate;

  @interface NSThread : NSObject {

  @private

  id _private;

  uint8_t _bytes[44];

  }

  + (NSThread *)currentThread;

  + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;

  + (BOOL)isMultiThreaded;

  - (NSMutableDictionary *)threadDictionary;

  + (void)sleepUntilDate:(NSDate *)date;

  + (void)sleepForTimeInterval:(NSTimeInterval)ti;

  + (void)exit;

  #if MAC_OS_X_VERSION_10_2 《= MAC_OS_X_VERSION_MAX_ALLOWED

  + (double)threadPriority;

  + (BOOL)setThreadPriority:(double)p;

  #endif

  #if MAC_OS_X_VERSION_10_5 《= MAC_OS_X_VERSION_MAX_ALLOWED

  + (NSArray *)callStackReturnAddresses;

  - (void)setName:(NSString *)n;

  - (NSString *)name;

  - (NSUInteger)stackSize;

  - (void)setStackSize:(NSUInteger)s;

  - (BOOL)isMainThread;

  + (BOOL)isMainThread; // reports whether current thread is main

  + (NSThread *)mainThread;

  - (id)init; // designated initializer

  - (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

  - (BOOL)isExecuting;

  - (BOOL)isFinished;

  - (BOOL)isCancelled;

  - (void)cancel;

  - (void)start;

  - (void)main; // thread body method

  #endif

  @end

  FOUNDATION_EXPORT NSString * const NSWillBecomeMultiThreadedNotification;

  FOUNDATION_EXPORT NSString * const NSDidBecomeSingleThreadedNotification;

  FOUNDATION_EXPORT NSString * const NSThreadWillExitNotification;

  @interface NSObject (NSThreadPerformAdditions)

  #if MAC_OS_X_VERSION_10_2 《= MAC_OS_X_VERSION_MAX_ALLOWED

  - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;

  - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

  // equivalent to the first method with kCFRunLoopCommonModes

  #endif

  #if MAC_OS_X_VERSION_10_5 《= MAC_OS_X_VERSION_MAX_ALLOWED

  - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;

  - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

  // equivalent to the first method with kCFRunLoopCommonModes

  - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;

  #endif

  @end

  Java因為其本身支持多線程而給程序員帶來很多方便,其實在iphone的開發中也支持多線程編程,并且一點也不比java麻煩。

  在這篇文章中,筆者就拿大多數Java教程中經典的“售票系統多線程”作為實際例子,在iphone中進行同樣的實現。

  下面是java版本的“售票系統多線程”代碼:

  package demo;

  public class SellTickets implements Runnable{

  private int tickets=100;

  public void run() {

  int count=0;

  while (true)

  {

  //上鎖

  synchronized(this){

  if (tickets》0){

  try {

  Thread.sleep(500);

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  count=100-tickets;

  System.out.println(“當前票數是:”+tickets+“售出”+count

  +“線程名:”+Thread.currentThread().getName());

  tickets--;

  }else{

  break;

  }

  }

  }

  }

  public static void main(String[] args) {

  SellTickets r=new SellTickets();

  Thread t1=new Thread(r,“t1”);

  t1.start();

  Thread t2=new Thread(r,“t2”);

  t2.start();

  Thread t3=new Thread(r,“t3”);

  t3.start();

  Thread t4=new Thread(r,“t4”);

  t4.start();

  }

  }

  以上java版本的代碼執行后控制臺輸出如下:

  當前票數是:100售出0線程名:t1

  當前票數是:99售出1線程名:t2

  當前票數是:98售出2線程名:t3

  當前票數是:97售出3線程名:t4

  當前票數是:96售出4線程名:t1

  當前票數是:95售出5線程名:t2

  當前票數是:94售出6線程名:t3

  當前票數是:93售出7線程名:t4

  當前票數是:92售出8線程名:t1

  當前票數是:91售出9線程名:t2

  當前票數是:90售出10線程名:t3

  當前票數是:89售出11線程名:t4

  當前票數是:88售出12線程名:t1

  當前票數是:87售出13線程名:t2

  當前票數是:86售出14線程名:t3

  當前票數是:85售出15線程名:t4

  當前票數是:84售出16線程名:t1

  當前票數是:83售出17線程名:t2

  當前票數是:82售出18線程名:t3

  當前票數是:81售出19線程名:t4

  當前票數是:80售出20線程名:t1

  當前票數是:79售出21線程名:t2

  當前票數是:78售出22線程名:t3

  當前票數是:77售出23線程名:t4

  當前票數是:76售出24線程名:t1

  當前票數是:75售出25線程名:t2

  當前票數是:74售出26線程名:t3

  當前票數是:73售出27線程名:t4

  ……

  可以在iphone中進行同樣的實現,Iphone的Frameworks/Foundation.framework框架支持多線程編程,接口定義在:

  /Xcode3.1.4/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSThread.h

  到相應的目錄下打開此文件,可以看到絕大多數java中的接口這里也都能找到相應的實現,如下:

  /* NSThread.h

  Copyright (c) 1994-2007, Apple Inc. All rights reserved.

  */

  #import 《Foundation/NSObject.h》

  #import 《Foundation/NSDate.h》

  @class NSArray, NSMutableDictionary, NSDate;

  @interface NSThread : NSObject {

  @private

  id _private;

  uint8_t _bytes[44];

  }

  + (NSThread *)currentThread;

  + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;

  + (BOOL)isMultiThreaded;

  - (NSMutableDictionary *)threadDictionary;

  + (void)sleepUntilDate:(NSDate *)date;

  + (void)sleepForTimeInterval:(NSTimeInterval)ti;

  + (void)exit;

  #if MAC_OS_X_VERSION_10_2 《= MAC_OS_X_VERSION_MAX_ALLOWED

  + (double)threadPriority;

  + (BOOL)setThreadPriority:(double)p;

  #endif

  #if MAC_OS_X_VERSION_10_5 《= MAC_OS_X_VERSION_MAX_ALLOWED

  + (NSArray *)callStackReturnAddresses;

  - (void)setName:(NSString *)n;

  - (NSString *)name;

  - (NSUInteger)stackSize;

  - (void)setStackSize:(NSUInteger)s;

  - (BOOL)isMainThread;

  + (BOOL)isMainThread; // reports whether current thread is main

  + (NSThread *)mainThread;

  - (id)init; // designated initializer

  - (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

  - (BOOL)isExecuting;

  - (BOOL)isFinished;

  - (BOOL)isCancelled;

  - (void)cancel;

  - (void)start;

  - (void)main; // thread body method

  #endif

  @end

  FOUNDATION_EXPORT NSString * const NSWillBecomeMultiThreadedNotification;

  FOUNDATION_EXPORT NSString * const NSDidBecomeSingleThreadedNotification;

  FOUNDATION_EXPORT NSString * const NSThreadWillExitNotification;

  @interface NSObject (NSThreadPerformAdditions)

  #if MAC_OS_X_VERSION_10_2 《= MAC_OS_X_VERSION_MAX_ALLOWED

  - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;

  - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

  // equivalent to the first method with kCFRunLoopCommonModes

  #endif

  #if MAC_OS_X_VERSION_10_5 《= MAC_OS_X_VERSION_MAX_ALLOWED

  - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;

  - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

  // equivalent to the first method with kCFRunLoopCommonModes

  - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;

  #endif

  @end

  從接口的定義中可以知道,NSThread和大多數iphone的接口對象一樣,有兩種方式可以初始化:

  一種使用initWithTarget :(id)target selector:(SEL)selector object:(id)argument,但需要負責在對象的retain count為0時調用對象的release方法清理對象。

  另一種則使用所謂的convenient method,這個方便接口就是detachNewThreadSelector,這個方法可以直接生成一個線程并啟動它,而且無需為線程的清理負責。

  因為在筆者的iphone版本“售票系統多線程”程序中需要設置線程的諸多參數,所以需要采用第一種方法來生成線程對象并自己啟動它們。

  首先,新建一個“Window-based Application”項目,并命名為SellTickets,接下來在SellTicketsAppDelegate.h文件中聲明以下變量:

  //

  // SellTicketsAppDelegate.h

  // SellTickets

  //

  // Created by sun dfsun2009 on 09-11-10.

  // Copyright __MyCompanyName__ 2009. All rights reserved.

  //

  #import 《UIKit/UIKit.h》

  @interface SellTicketsAppDelegate : NSObject 《UIApplicationDelegate》 {

  int tickets;

  int count;

  NSThread* ticketsThreadone;

  NSThread* ticketsThreadtwo;

  UIWindow *window;

  }

  @property (nonatomic, retain) IBOutlet UIWindow *window;

  @end

  筆者在頭文件中聲明了兩個NSThread的指針,下面需要在*.m文件中初始化并實現它們,如下:

  //

  // SellTicketsAppDelegate.m

  // SellTickets

  //

  // Created by sun dfsun2009 on 09-11-10.

  // Copyright __MyCompanyName__ 2009. All rights reserved.

  //

  #import “SellTicketsAppDelegate.h”

  @implementation SellTicketsAppDelegate

  @synthesize window;

  - (void)applicationDidFinishLaunching:(UIApplication *)application {

  tickets = 100;

  count = 0;

  ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];

 ?。踭icketsThreadone setName:@“Thread-1”];

 ?。踭icketsThreadone start];

  ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];

  [ticketsThreadtwo setName:@“Thread-2”];

 ?。踭icketsThreadtwo start];

  //[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

  // Override point for customization after application launch

  [window makeKeyAndVisible];

  }

  - (void)run{

  while (TRUE) {

  if(tickets 》 0)

  {

 ?。跱SThread sleepForTimeInterval:0.5];

  count = 100 - tickets;

  NSLog(@“當前票數是:%d,售出:%d,線程名:%@”,tickets,count,[[NSThread currentThread] name]);

  tickets--;

  }else

  {

  break;

  }

  }

  }

  - (void)dealloc {

 ?。踭icketsThreadone release];

  [ticketsThreadtwo release];

 ?。踳indow release];

 ?。踫uper dealloc];

  }

  @end

  筆者在實現中用alloc初始化了兩個NSThread對象并分別把它們命名為“Thread-1”和“Thread-2”,運行程序可以看到如下輸出:

 ?。跾ession started at 2009-11-10 14:25:26 +0800.]

  2009-11-10 14:25:28.814 SellTickets[1298:4103] 當前票數是:100,售出:0,線程名:Thread-1

  2009-11-10 14:25:28.814 SellTickets[1298:4203] 當前票數是:100,售出:0,線程名:Thread-2

  2009-11-10 14:25:29.316 SellTickets[1298:4103] 當前票數是:98,售出:2,線程名:Thread-1

  2009-11-10 14:25:29.316 SellTickets[1298:4203] 當前票數是:98,售出:2,線程名:Thread-2

  2009-11-10 14:25:29.817 SellTickets[1298:4103] 當前票數是:96,售出:4,線程名:Thread-1

  2009-11-10 14:25:29.817 SellTickets[1298:4203] 當前票數是:96,售出:4,線程名:Thread-2

  2009-11-10 14:25:30.318 SellTickets[1298:4103] 當前票數是:94,售出:6,線程名:Thread-1

  2009-11-10 14:25:30.318 SellTickets[1298:4203] 當前票數是:94,售出:6,線程名:Thread-2

  2009-11-10 14:25:30.819 SellTickets[1298:4103] 當前票數是:92,售出:8,線程名:Thread-1

  2009-11-10 14:25:30.819 SellTickets[1298:4203] 當前票數是:92,售出:8,線程名:Thread-2

  2009-11-10 14:25:31.320 SellTickets[1298:4103] 當前票數是:90,售出:10,線程名:Thread-1

  2009-11-10 14:25:31.320 SellTickets[1298:4203] 當前票數是:90,售出:10,線程名:Thread-2

  2009-11-10 14:25:31.820 SellTickets[1298:4103] 當前票數是:88,售出:12,線程名:Thread-1

  2009-11-10 14:25:31.821 SellTickets[1298:4203] 當前票數是:87,售出:13,線程名:Thread-2

  2009-11-10 14:25:32.321 SellTickets[1298:4103] 當前票數是:86,售出:14,線程名:Thread-1

  2009-11-10 14:25:32.322 SellTickets[1298:4203] 當前票數是:86,售出:14,線程名:Thread-2

  2009-11-10 14:25:32.823 SellTickets[1298:4103] 當前票數是:84,售出:16,線程名:Thread-1

  2009-11-10 14:25:32.823 SellTickets[1298:4203] 當前票數是:83,售出:17,線程名:Thread-2

  2009-11-10 14:25:33.323 SellTickets[1298:4103] 當前票數是:82,售出:18,線程名:Thread-1

  2009-11-10 14:25:33.324 SellTickets[1298:4203] 當前票數是:81,售出:19,線程名:Thread-2

  2009-11-10 14:25:33.824 SellTickets[1298:4103] 當前票數是:80,售出:20,線程名:Thread-1

  2009-11-10 14:25:33.825 SellTickets[1298:4203] 當前票數是:79,售出:21,線程名:Thread-2

  2009-11-10 14:25:34.325 SellTickets[1298:4103] 當前票數是:78,售出:22,線程名:Thread-1

  2009-11-10 14:25:34.326 SellTickets[1298:4203] 當前票數是:77,售出:23,線程名:Thread-2

  2009-11-10 14:25:34.826 SellTickets[1298:4103] 當前票數是:76,售出:24,線程名:Thread-1

  2009-11-10 14:25:34.827 SellTickets[1298:4203] 當前票數是:75,售出:25,線程名:Thread-2

  2009-11-10 14:25:35.327 SellTickets[1298:4103] 當前票數是:74,售出:26,線程名:Thread-1

  2009-11-10 14:25:35.328 SellTickets[1298:4203] 當前票數是:73,售出:27,線程名:Thread-2

  2009-11-10 14:25:35.827 SellTickets[1298:4103] 當前票數是:72,售出:28,線程名:Thread-1

  2009-11-10 14:25:35.830 SellTickets[1298:4203] 當前票數是:71,售出:29,線程名:Thread-2

  2009-11-10 14:25:36.329 SellTickets[1298:4103] 當前票數是:70,售出:30,線程名:Thread-1

  2009-11-10 14:25:36.330 SellTickets[1298:4203] 當前票數是:69,售出:31,線程名:Thread-2

  2009-11-10 14:25:36.830 SellTickets[1298:4103] 當前票數是:68,售出:32,線程名:Thread-1

  2009-11-10 14:25:36.831 SellTickets[1298:4203] 當前票數是:67,售出:33,線程名:Thread-2

  2009-11-10 14:25:37.331 SellTickets[1298:4103] 當前票數是:66,售出:34,線程名:Thread-1

  2009-11-10 14:25:37.332 SellTickets[1298:4203] 當前票數是:65,售出:35,線程名:Thread-2

  2009-11-10 14:25:37.832 SellTickets[1298:4103] 當前票數是:64,售出:36,線程名:Thread-1

  2009-11-10 14:25:37.833 SellTickets[1298:4203] 當前票數是:63,售出:37,線程名:Thread-2

  2009-11-10 14:25:38.333 SellTickets[1298:4103] 當前票數是:62,售出:38,線程名:Thread-1

  2009-11-10 14:25:38.334 SellTickets[1298:4203] 當前票數是:61,售出:39,線程名:Thread-2

  2009-11-10 14:25:38.834 SellTickets[1298:4103] 當前票數是:60,售出:40,線程名:Thread-1

  2009-11-10 14:25:38.836 SellTickets[1298:4203] 當前票數是:59,售出:41,線程名:Thread-2

  2009-11-10 14:25:39.335 SellTickets[1298:4103] 當前票數是:58,售出:42,線程名:Thread-1

  2009-11-10 14:25:39.337 SellTickets[1298:4203] 當前票數是:58,售出:42,線程名:Thread-2

  2009-11-10 14:25:39.838 SellTickets[1298:4103] 當前票數是:56,售出:44,線程名:Thread-1

  2009-11-10 14:25:39.839 SellTickets[1298:4203] 當前票數是:55,售出:45,線程名:Thread-2

  2009-11-10 14:25:40.339 SellTickets[1298:4103] 當前票數是:54,售出:46,線程名:Thread-1

  2009-11-10 14:25:40.340 SellTickets[1298:4203] 當前票數是:53,售出:47,線程名:Thread-2

  2009-11-10 14:25:40.840 SellTickets[1298:4103] 當前票數是:52,售出:48,線程名:Thread-1

  2009-11-10 14:25:40.841 SellTickets[1298:4203] 當前票數是:51,售出:49,線程名:Thread-2

  2009-11-10 14:25:41.341 SellTickets[1298:4103] 當前票數是:50,售出:50,線程名:Thread-1

  2009-11-10 14:25:41.342 SellTickets[1298:4203] 當前票數是:49,售出:51,線程名:Thread-2

  2009-11-10 14:25:41.842 SellTickets[1298:4103] 當前票數是:48,售出:52,線程名:Thread-1

  2009-11-10 14:25:41.843 SellTickets[1298:4203] 當前票數是:47,售出:53,線程名:Thread-2

  2009-11-10 14:25:42.343 SellTickets[1298:4103] 當前票數是:46,售出:54,線程名:Thread-1

  2009-11-10 14:25:42.344 SellTickets[1298:4203] 當前票數是:45,售出:55,線程名:Thread-2

  2009-11-10 14:25:42.844 SellTickets[1298:4103] 當前票數是:44,售出:56,線程名:Thread-1

  2009-11-10 14:25:42.845 SellTickets[1298:4203] 當前票數是:43,售出:57,線程名:Thread-2

  2009-11-10 14:25:43.345 SellTickets[1298:4103] 當前票數是:42,售出:58,線程名:Thread-1

  2009-11-10 14:25:43.346 SellTickets[1298:4203] 當前票數是:42,售出:58,線程名:Thread-2

  2009-11-10 14:25:43.846 SellTickets[1298:4103] 當前票數是:40,售出:60,線程名:Thread-1

  2009-11-10 14:25:43.847 SellTickets[1298:4203] 當前票數是:39,售出:61,線程名:Thread-2

  2009-11-10 14:25:44.347 SellTickets[1298:4103] 當前票數是:38,售出:62,線程名:Thread-1

  2009-11-10 14:25:44.348 SellTickets[1298:4203] 當前票數是:37,售出:63,線程名:Thread-2

  2009-11-10 14:25:44.848 SellTickets[1298:4103] 當前票數是:36,售出:64,線程名:Thread-1

  2009-11-10 14:25:44.849 SellTickets[1298:4203] 當前票數是:35,售出:65,線程名:Thread-2

  2009-11-10 14:25:45.349 SellTickets[1298:4103] 當前票數是:34,售出:66,線程名:Thread-1

  2009-11-10 14:25:45.350 SellTickets[1298:4203] 當前票數是:33,售出:67,線程名:Thread-2

  2009-11-10 14:25:45.850 SellTickets[1298:4103] 當前票數是:32,售出:68,線程名:Thread-1

  2009-11-10 14:25:45.851 SellTickets[1298:4203] 當前票數是:31,售出:69,線程名:Thread-2

  2009-11-10 14:25:46.350 SellTickets[1298:4103] 當前票數是:30,售出:70,線程名:Thread-1

  2009-11-10 14:25:46.351 SellTickets[1298:4203] 當前票數是:29,售出:71,線程名:Thread-2

  2009-11-10 14:25:46.851 SellTickets[1298:4103] 當前票數是:28,售出:72,線程名:Thread-1

  2009-11-10 14:25:46.853 SellTickets[1298:4203] 當前票數是:27,售出:73,線程名:Thread-2

  2009-11-10 14:25:47.352 SellTickets[1298:4103] 當前票數是:26,售出:74,線程名:Thread-1

  2009-11-10 14:25:47.354 SellTickets[1298:4203] 當前票數是:25,售出:75,線程名:Thread-2

  可以看到,因為兩個線程共享變量tickets和count,開頭的輸出就產生了異常情況,iphone雖然沒有提供類似java下的synchronized關鍵字,但提供了NSCondition對象接口。查看NSCondition的接口說明可以看出,NSCondition是iphone下的鎖對象,所以我們需要讓代碼成為線程安全的,修改頭文件如下:

  //

  // SellTicketsAppDelegate.h

  // SellTickets

  //

  // Created by sun dfsun2009 on 09-11-10.

  // Copyright __MyCompanyName__ 2009. All rights reserved.

  //

  #import 《UIKit/UIKit.h》

  @interface SellTicketsAppDelegate : NSObject 《UIApplicationDelegate》 {

  int tickets;

  int count;

  NSThread* ticketsThreadone;

  NSThread* ticketsThreadtwo;

  NSCondition* ticketsCondition;

  UIWindow *window;

  }

  @property (nonatomic, retain) IBOutlet UIWindow *window;

  @end

  然后在實現中添加如下代碼:

  //

  // SellTicketsAppDelegate.m

  // SellTickets

  //

  // Created by sun dfsun2009 on 09-11-10.

  // Copyright __MyCompanyName__ 2009. All rights reserved.

  //

  #import “SellTicketsAppDelegate.h”

  @implementation SellTicketsAppDelegate

  @synthesize window;

  - (void)applicationDidFinishLaunching:(UIApplication *)application {

  tickets = 100;

  count = 0;

  // 鎖對象

  ticketCondition = [[NSCondition alloc] init];

  ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];

 ?。踭icketsThreadone setName:@“Thread-1”];

 ?。踭icketsThreadone start];

  ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];

  [ticketsThreadtwo setName:@“Thread-2”];

 ?。踭icketsThreadtwo start];

  //[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

  // Override point for customization after application launch

  [window makeKeyAndVisible];

  }

  - (void)run{

  while (TRUE) {

  // 上鎖

 ?。踭icketsCondition lock];

  if(tickets 》 0)

  {

  [NSThread sleepForTimeInterval:0.5];

  count = 100 - tickets;

  NSLog(@“當前票數是:%d,售出:%d,線程名:%@”,tickets,count,[[NSThread currentThread] name]);

  tickets--;

  }else

  {

  break;

  }

 ?。踭icketsCondition unlock];

  }

  }

  - (void)dealloc {

 ?。踭icketsThreadone release];

 ?。踭icketsThreadtwo release];

 ?。踭icketsCondition release];

  [window release];

 ?。踫uper dealloc];

  }

  @end

  最后千萬別忘記在dealloc方法中調用對象的release進行資源釋放,現在再次運行下看看,iphone版本的“售票系統多線程”程序是否跑起來了:)。

此內容為AET網站原創,未經授權禁止轉載。
热re99久久精品国产66热_欧美小视频在线观看_日韩成人激情影院_庆余年2免费日韩剧观看大牛_91久久久久久国产精品_国产原创欧美精品_美女999久久久精品视频_欧美大成色www永久网站婷_国产色婷婷国产综合在线理论片a_国产精品电影在线观看_日韩精品视频在线观看网址_97在线观看免费_性欧美亚洲xxxx乳在线观看_久久精品美女视频网站_777国产偷窥盗摄精品视频_在线日韩第一页
  • <strike id="ygamy"></strike>
  • 
    
      • <del id="ygamy"></del>
        <tfoot id="ygamy"></tfoot>
          <strike id="ygamy"></strike>
          久久久久久黄| 久久se精品一区精品二区| 国产婷婷一区二区| 久久久综合免费视频| 一区二区在线观看视频在线观看| 日韩视频免费观看高清完整版| 国产一区视频在线看| 欧美成人精品不卡视频在线观看| 国产字幕视频一区二区| 欧美aa国产视频| 欧美日韩亚洲一区二区三区在线观看| 久久婷婷色综合| 欧美久久综合| 国产一区二区精品久久99| 欧美在线1区| 国产伦精品一区二区三区高清版| 欧美一级久久久久久久大片| 欧美韩日亚洲| 亚洲最新合集| 国产精品久在线观看| 亚洲精品免费电影| 欧美一区二区三区视频在线观看| 久久国产精品电影| 欧美午夜精品电影| 亚洲经典三级| 91久久久一线二线三线品牌| 一区二区三区久久网| 久久美女艺术照精彩视频福利播放| 国产精品一二三四| 亚洲国产婷婷综合在线精品| 国产精品捆绑调教| 永久免费毛片在线播放不卡| 欧美日韩国产综合新一区| 极品尤物久久久av免费看| 亚洲激情婷婷| 欧美激情视频在线免费观看 欧美视频免费一| 欧美性猛交99久久久久99按摩| 欧美精选午夜久久久乱码6080| 亚洲自拍啪啪| 狠狠狠色丁香婷婷综合激情| 久久精品一区二区三区中文字幕| 欧美视频中文一区二区三区在线观看| 亚洲精品综合久久中文字幕| 亚洲午夜激情免费视频| 在线成人中文字幕| 老色鬼久久亚洲一区二区| 老司机精品视频网站| 欧美专区第一页| 一区二区在线观看视频在线观看| 亚洲免费在线| 午夜精品久久久久久久久| 欧美自拍偷拍午夜视频| 国产精品视频久久一区| 欧美国产日韩视频| 国产乱肥老妇国产一区二| 久久久国产精彩视频美女艺术照福利| 国产精品成av人在线视午夜片| 先锋影音一区二区三区| 99热免费精品在线观看| 亚洲激情成人在线| 亚洲国产美国国产综合一区二区| 亚洲天堂免费在线观看视频| 欧美性jizz18性欧美| 中文国产一区| 在线视频一区观看| 久久www成人_看片免费不卡| 狠狠综合久久av一区二区老牛| 理论片一区二区在线| 国产精品久久久亚洲一区| 亚洲欧美精品suv| 久久精品在这里| 伊人成综合网伊人222| 国产欧美亚洲精品| 欧美成人一区在线| 在线看片成人| 国产精品久久久999| 国内精品模特av私拍在线观看| 一本一本久久a久久精品综合妖精| 欧美日韩日本视频| 欧美日韩免费看| 国产婷婷精品| 国产精品人人爽人人做我的可爱| 国产日韩亚洲欧美综合| 欧美在线视频日韩| 在线观看日韩www视频免费| 久久免费观看视频| 欧美日韩三区四区| 国产一区二区欧美| 亚洲欧美激情精品一区二区| 久久久久成人精品免费播放动漫| 国产一区自拍视频| 久久国产日本精品| 亚洲成人中文| 欧美日韩亚洲一区二区三区在线观看| 欧美日韩国产综合在线| 亚洲桃花岛网站| 欧美精品成人91久久久久久久| 欧美视频在线视频| 9i看片成人免费高清| 国产亚洲一区二区在线观看| 亚洲精品国偷自产在线99热| 在线观看亚洲专区| 亚洲系列中文字幕| 欧美日韩一区三区| 国产伦精品一区二区三区高清| 欧美视频在线观看免费| 欧美在线一二三| 国产一区香蕉久久| 欧美日韩视频在线观看一区二区三区| 亚洲精品在线视频| 日韩视频免费观看高清在线视频| 国产裸体写真av一区二区| 欧美日韩在线播| 老司机aⅴ在线精品导航| 国产精品日韩精品| 亚洲人体影院| 一区二区欧美视频| 欧美日韩国产系列| 黄色一区二区三区| 欧美超级免费视 在线| 蜜臀久久久99精品久久久久久| 国产综合婷婷| 欧美日韩中文字幕综合视频| 国产精品v欧美精品v日本精品动漫| 亚洲精品乱码久久久久久| 亚洲第一福利在线观看| 免费不卡视频| 欧美高清在线视频观看不卡| 国产主播一区二区| 国产日韩一区二区三区在线| 蜜臀av在线播放一区二区三区| 亚洲精品美女免费| 免费在线亚洲欧美| 国产性猛交xxxx免费看久久| 久久午夜精品一区二区| 亚洲第一久久影院| 欧美理论片在线观看| 日韩视频一区二区三区在线播放| 久久精品国产99国产精品| 国产九九精品| 黄色亚洲大片免费在线观看| 红桃视频国产一区| 亚洲乱码久久| 久久综合999| 悠悠资源网久久精品| 一区免费观看| 久久亚洲精品中文字幕冲田杏梨| 欧美日韩中国免费专区在线看| 欧美午夜三级| 99视频在线观看一区三区| 午夜精品婷婷| 久久久久国产精品一区| 91久久国产综合久久| 国产精品www994| 久久精品人人做人人综合| 亚洲午夜激情网页| 久久国产福利国产秒拍| 亚洲美女黄色片| 久久久久国色av免费看影院| 日韩视频中文字幕| 亚洲美女视频在线观看| 久久激情视频免费观看| 午夜一区不卡| 亚洲精品久久嫩草网站秘色| 欧美日韩午夜激情| 亚洲欧洲av一区二区三区久久| 欧美日韩一二三区| 亚洲欧美日韩在线不卡| 国产精品视频久久久| 在线成人av网站| 久久精品免费观看| 国产亚洲va综合人人澡精品| 亚洲欧洲在线播放| 久久精品视频免费观看| 欧美成人免费全部| 欧美理论视频| 99精品热6080yy久久| 国产欧美午夜| 亚洲国产精品高清久久久| 国产亚洲第一区| 国产精品99一区二区| 久久久亚洲影院你懂的| 亚洲欧美国产制服动漫| 99国产精品久久久久久久成人热| 国产拍揄自揄精品视频麻豆| 麻豆国产精品一区二区三区| 欧美成人性网| 黄色成人在线观看| 中文高清一区| 亚洲电影免费在线观看| 久久精品久久99精品久久| 久久久五月天| 国产在线观看一区| 亚洲电影中文字幕| 欧美日韩在线不卡一区| 最新日韩精品| 在线视频成人| 亚洲图片欧美日产| 国产欧美日韩在线播放| 欧美激情亚洲一区| 欧美国产亚洲精品久久久8v| 日韩亚洲欧美综合| 国产视频一区在线观看一区免费| 欧美日韩大陆在线| 亚洲一级片在线观看| 亚洲啪啪91| 亚洲精品护士| 翔田千里一区二区| 午夜精品免费在线| 亚洲香蕉在线观看| 久久久久久亚洲精品杨幂换脸| 久久精品日韩一区二区三区| 国精品一区二区| 久久国产夜色精品鲁鲁99| 欧美日韩国产一级| 狂野欧美性猛交xxxx巴西| 一区二区三区在线免费视频| 亚洲国产精品电影| 国产欧美日韩一区二区三区| 国产一区二区三区日韩| 国产午夜精品视频免费不卡69堂| 狠狠综合久久av一区二区小说| 欧美激情无毛| 亚洲主播在线播放| 99精品久久免费看蜜臀剧情介绍| 国产精品视频yy9299一区| 久久久久久久久久码影片| 亚洲国产精品va| 免费日韩精品中文字幕视频在线| 欧美电影在线播放| 欧美成人视屏| 国产精品视频久久久| 欧美日韩一区在线视频| 欧美日韩国产在线播放网站| 亚洲一区影院| 国产伦精品一区二区三区照片91| 亚洲激情视频在线播放| 亚洲一区二区黄色| 久久爱www久久做| 亚洲网站在线播放| 欧美国产精品v| 国产亚洲va综合人人澡精品| 激情婷婷亚洲| 亚洲第一伊人| 亚洲欧美自拍偷拍| 久久婷婷综合激情| 一区福利视频| 久久综合伊人77777麻豆| 一区二区激情视频| 欧美特黄一级大片| 国产精品麻豆欧美日韩ww| 91久久精品国产| 欧美日韩二区三区| 亚洲性夜色噜噜噜7777| 久久久久一区二区三区| 亚洲国产天堂网精品网站| 在线日韩日本国产亚洲| 亚洲午夜国产成人av电影男同| 久久五月天婷婷| 国产精品成人av性教育| 午夜精品一区二区三区在线视| 欧美sm极限捆绑bd| 亚洲一区日本| 久久九九99视频| 亚洲欧美资源在线| 亚洲午夜日本在线观看| 亚洲一区3d动漫同人无遮挡| 国产精品亚洲产品| 国内揄拍国内精品久久| 欧美日韩国产一区精品一区| 亚洲免费观看高清完整版在线观看熊| 一区二区三区免费观看| 日韩亚洲在线观看| 国产日韩欧美自拍| 欧美三日本三级三级在线播放| 亚洲欧美日韩第一区| 狠狠色狠狠色综合日日五| 久久福利一区| 在线中文字幕不卡| 亚洲国产精品专区久久| 国产精品久久久久av免费| 欧美日本国产精品| 久久精品免费| 欧美电影在线| 久久亚洲国产精品日日av夜夜| 欧美成人在线免费视频| 亚洲欧美日韩专区| 激情亚洲成人| 亚洲欧美日韩精品在线| 欧美va日韩va| 亚洲午夜精品久久久久久浪潮| 国产一二精品视频| 久久大香伊蕉在人线观看热2| 亚洲裸体视频| 日韩亚洲视频| 亚洲一区3d动漫同人无遮挡| 激情综合激情| 亚洲国产精品高清久久久| 国产酒店精品激情| 亚洲一区二区三区中文字幕在线| 亚洲日本免费电影| 欧美精品国产精品日韩精品| 午夜在线一区二区| 国产精品日韩久久久久| 在线精品视频一区二区三四| 在线观看欧美一区| 亚洲一区二区三区中文字幕在线| 久久成人免费网| 有坂深雪在线一区| 国产一区二区三区视频在线观看| 欧美成人免费网| 伊人久久大香线蕉av超碰演员| 亚洲六月丁香色婷婷综合久久| 亚洲国产成人精品视频| 国产精品系列在线| 欧美日韩精品久久| 国产美女精品| 日韩亚洲国产欧美| 国产在线一区二区三区四区| 欧美三日本三级少妇三99| 欧美大片va欧美在线播放| 国产精品一区免费在线观看| 欧美在线视频导航| 欧美三区免费完整视频在线观看| 亚洲韩国精品一区| 中文国产成人精品| 久久都是精品| 亚洲香蕉在线观看|