多线程

// 多线程
   
// 单线程 : 在应用程序启动的时候 , 会自动创建一个线程。该线程为主线程。只有一个主线程的应用程序为单线程应用程序。在主线程的代码会顺序执行。
   
// 单线程程序的问题 : 在程序运行的过程中难免会需要请求数据、解析数据等等很多耗时的任务。这时如果把所有的任务都放在主线程中执行会造成程序的假死现象 , 用户交互不好。
   
// 为了提高用户的交互性 , 可以采用多线程。
   
// 多线程 : 即程序中不仅仅有一个主线程。这些子线程主要用来进行一些复杂的工作。
   
// 使用多线程注意事项 : 不管开辟的多少个子线程 , 最终 UI 界面的刷新和展示 ( 即所有对 UI 的操作 ) 都需要回到主线程中执行。 ==>> 问题 : 如何从子线程回到主线程 ?
   
// 使用多线程的优缺点 :
              
// 优点 : 可以防止主线程阻塞 , 提用户交互性。
              
// 缺点 : 1. 在开辟子线程的时候需要耗费一定的资源。
               //      2. 不管开辟了多少个子线程最终要回到主线程 , 这时也需要耗
                                                      CPU 性能。 
               //      3. 子线程开辟过多少会造成代码可读性比较差。
   
//  问题一 : 如何从子线程回到主线程 :
    
// 1.NSObject 对应的方法 :performSelectorOnMainThread
     // 2.dispatch_async(dispatch_get_main_queue(), ^{});


  /******************** 第一种方式 NSThread********************/
   
// 获取当前的线程 (thread)
   
NSLog ( @"mainThread:%@" , [ NSThread currentThread ]);
   
//  initWithTarget:selector:object: 参数含义如下 :
     
// 1. 目标
     
// 2. 方法名
     
// 3. 方法对于的参数
//  在使用下列方法时需要注意该方法不会自动开辟子线程执行方法 , 需要手动调用 start 开启。 ( 开辟子线程 )
//    NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(calculate:) object:self.NumberTF.text];
//    // 开启
//    [thread1 start];
   
   
// 这个方法使用会立即跳到子线程 , 不需要手动 Start
    [NSThread detachNewThreadSelector:@selector(calculate:) toTarget:self withObject:self.NumberTF.text];

    // 在子线程里加载图片 , 然后回到主线程显示图片
   
/*************** 方式二使用 NSObject*****************/
   
NSURL *url = [ NSURL URLWithString : kURL ];
#pragma mark - 该方法是 NSObject 的方法 , 凡是继承 NSObject 的类都可以使用该方法。该方法调用几次就会开辟几个子线程。 ==> 问题 : 如果不同线程争夺同一个资源 , 咋办 ?
//    @synchronized(<#token#>) {     // 线程锁方法一
//        <#statements#>
//    }
    [self performSelectorInBackground:@selector(downloadMyImage:) withObject:url]; // 开启子线程

    /************ 方式三 使用 NSOperationQueue*************/
   
// NSOperationQueue: 操作队列。用来管理一组操作 (NSOperation)
   
// 注意事项 :NSOperationQueue 开辟线程的个数是由系统决定的。不是由操作的个数决定的。 ( ⭐️⭐️⭐️⭐️⭐️ ) ==> 面试题 !!!
   
// 创建两个 NSOperation(NSBlockOperation\ NSInvocation)
   
NSBlockOperation *blockOp = [ NSBlockOperation blockOperationWithBlock :^{
       
NSLog ( @"blockThread:%@" , [ NSThread currentThread ]);
    }];
   
NSInvocationOperation *invocationOp = [[ NSInvocationOperation alloc ] initWithTarget : self selector : @selector (calculate:) object : @"50" ];
   
   
NSOperationQueue *queue = [[ NSOperationQueue alloc ] init ];
#pragma mark - 下列方法中参数的含义 :
    // 1. 操作对应的数组
   
// 2.BOOL: 如果给的是 YES, 那么会阻塞当前线程 , 直到操作队列里面所有的操作被执行完 , 当前线程才不会被阻塞。
//  如果给的是 NO, 那么不会阻塞当前线程。
//  可能会产生的问题 : 如果给的是 YES, 而且卡死的是主线程。那么在操作中如果需要对 UI 进行操作需要返回到主线程中去执行代码。这时程序就会出现死锁 ( 一直出不来 , 按键也一直不能再次点击 )
   
// 设置最大并发数为 1.( 当前在操作队列中正在运行的任务只有一个。与线程个数无关。 )
   
// 如果设置最大并发数为 1, 那么可以实现线程同步。
   
// 线程同步 : 只有当一个线程中的任务执行完毕之后 , 才能执行另外一个线程的任务。
    queue.
maxConcurrentOperationCount = 1 ;
    [queue addOperations:@[blockOp, invocationOp] waitUntilFinished:NO];

/************************* 方式四 GCD************************/
// GCD 的核心是分发队列。
// 分发队列有两种形式 :
      
// 串行队列 : 一次只能执行一个任务。如果有多个串行队列那么每个队列中的任务都是同步执行的 , 但是队列之间可以并发执行 ( 互不干扰 )
      
// 并行队列 : 并发的执行多个任务。但是 FIFO.( 只支持先进 , 并不一定先出。 )
- (
IBAction )serialQueue:( id )sender {
   
// 串行队列有两种形式 :
       
// 1. 系统提供的 :dispatch_async(dispatch_get_main_queue: 主队列 ==>> 在主线程中。
   
dispatch_async ( dispatch_get_main_queue (), ^{
       
NSLog ( @" 下载图片 :%@" , [ NSThread currentThread ]);
    });
       
// 2. 自己创建的 ( 自己创建的会再子线程 )
   
dispatch_queue_t queue = dispatch_queue_create ( "com.fy.queue1" , DISPATCH_QUEUE_SERIAL );
   
dispatch_async (queue, ^{
       
NSLog ( @"thread:%@" , [ NSThread currentThread ]); // 子线程中
    });
   
// 串行是顺序执行
   
dispatch_async (queue, ^{
       
NSLog ( @" 小米出生了 " );
    });
   
dispatch_async (queue, ^{
       
NSLog ( @" 小米上学了 " );
    });
   
dispatch_async (queue, ^{
       
NSLog ( @" 小米结婚了 " );
    });
   
dispatch_async (queue, ^{
       
NSLog ( @" 小米有宝宝了 " );
    });
   
}

- (
IBAction )concurrentQueue:( id )sender {
   
// 并行队列有两种 :
       
// 1. 系统提供的 ( 也是子线程 )
   
dispatch_async ( dispatch_get_global_queue ( DISPATCH_QUEUE_PRIORITY_DEFAULT , 0 ), ^{
       
NSLog ( @"======:%@" , [ NSThread currentThread ]);
    });
   
       
// 2. 自己创建的
   
dispatch_queue_t concurrentQueue = dispatch_queue_create ( "com.fy.concurrentQueue" , DISPATCH_QUEUE_CONCURRENT );
   
dispatch_async (concurrentQueue, ^{
       
NSLog ( @"thread:%@" , [ NSThread currentThread ]); // 子线程中
    });
   
// 并行队列与顺序没有关系 , 是无序的
   
dispatch_async (concurrentQueue, ^{
       
NSLog ( @" 小米出生了 " );
    });
   
dispatch_async (concurrentQueue, ^{
       
NSLog ( @" 小米上学了 " );
    });
   
dispatch_async (concurrentQueue, ^{
       
NSLog ( @" 小米结婚了 " );
    });
   
dispatch_async (concurrentQueue, ^{
       
NSLog ( @" 小米有宝宝了 " );
    });
}

// 使用 GCD
- (
IBAction )useGCD:( id )sender {
   
dispatch_queue_t myQueue = dispatch_queue_create ( "com.fy.myQueue" , DISPATCH_QUEUE_SERIAL );
   
dispatch_async (myQueue, ^{
       
UIImage *image = [ UIImage imageWithData :[ NSData dataWithContentsOfURL :[ NSURL URLWithString : kImage ]]];
       
dispatch_async ( dispatch_get_main_queue (), ^{
           
self . imageView . image = image;
        });
    });
}
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值