<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[gaoxiaoweiandy的专栏]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/gaoxiaoweiandy</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; gaoxiaoweiandy]]></copyright><item><title><![CDATA[40岁大龄程序员真实变形记（一）]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/145231061</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/145231061</guid><author>gaoxiaoweiandy</author><pubDate>Sat, 18 Jan 2025 19:05:46 +0800</pubDate><description><![CDATA[当这个餐厅拉了新的宽带后，将要重新调试一遍。但是，当下完单后，“下单”按钮仍然是醒目的橙黄色，按理来说应该让“结账”按钮变成醒目的橙黄色，“下单”按钮置为灰色，因为下一个步骤，一般用户想要操作的是“结账”。制作这些文档与视频一方面是为客户服务的，同时也是为我自己服务的，留给我以后参考用的，更重要的是快速应对，引导客户自学，减轻自己工作量的一个重要手段。在对客户提供技术支持的过程中，更是收集了用户提出的问题，了解了用户常用的功能是什么，餐饮行业用的最多的就是会员，外卖功能，零售行业用的最多的就是进销存功能。]]></description><category></category></item><item><title><![CDATA[FFMPEG（三）编译脚本中的FLAGS如何编写]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/125834044</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/125834044</guid><author>gaoxiaoweiandy</author><pubDate>Sun, 17 Jul 2022 17:13:15 +0800</pubDate><description><![CDATA[编译脚本]]></description><category></category></item><item><title><![CDATA[FFMPEG(二) FFMPEG编译出的库说明]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/125805002</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/125805002</guid><author>gaoxiaoweiandy</author><pubDate>Fri, 15 Jul 2022 15:05:12 +0800</pubDate><description><![CDATA[FFPGE编译出的库说明]]></description><category></category></item><item><title><![CDATA[线程并发相关的原子操作类]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/122721251</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/122721251</guid><author>gaoxiaoweiandy</author><pubDate>Mon, 31 Jan 2022 00:00:00 +0800</pubDate><description><![CDATA[#线程并发原子操作类
何为原子性，就是一次性操作完成，在操作变量的时候，其它线程不能操作变量，也就是我们之前说的synchronized同步关键字的作用。这节我们不用synchronized，而是用系统API中的原子类，今天我们以其中一个AtomicInteger类为例来讲解。
比如我们有20个人同时卖票，每人卖1000张，问最后总共卖了多少张？这里先给出答案：20000张。
我们来看下代码如何编写，20个人相当于20个线程，然后每个线程内for循环1000次，每次给票数加1，那么java代码就是：
模拟2]]></description><category></category></item><item><title><![CDATA[线程范围内共享变量，使用ThreadLocal API来实现]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/122666515</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/122666515</guid><author>gaoxiaoweiandy</author><pubDate>Mon, 24 Jan 2022 14:12:41 +0800</pubDate><description><![CDATA[1.回顾
上节我们讲了线程共享范围内的共享变量，我们使用了一个Map(K,V),其中Key为正在执行的线程对象，value存储的是线程操作的变量，如一个int型的data，我们以key来区分是哪一个对象所操作的变量。这一节我们将使用ThreadLocal 这个线程范围内共享变量的专用API来实现。
2.使用ThreadLocal实现
2.1 使用ThreadLocal实现基本数据类型在线程范围内共享
使用ThreadLocal实现线程范围内的共享变量。代码如下：
public class ThreadSha]]></description><category></category></item><item><title><![CDATA[线程范围内的共享变量]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/122635736</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/122635736</guid><author>gaoxiaoweiandy</author><pubDate>Sat, 22 Jan 2022 14:04:04 +0800</pubDate><description><![CDATA[1. 线程范围内的共享变量的概念

     假设有2个线程，一个全局变量 int data。2个线程内的代码共用这一个变量的声明（data），但它们操作data时，data的值在这2个线程里是独立的，互不影响的。我们这里所说的互不影响，不是我们之前说的syncronized,（线程1先修改data值，读取data值，释放锁后，线程2才可修改data和读取data,这样的话data最终的值还会变为线程2最后修改的值）。我们现在要实现的是，线程1修改了data=1, 线程2也修改了同一个data变量...]]></description><category></category></item><item><title><![CDATA[线程间的通信notify与wait]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/122312928</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/122312928</guid><author>gaoxiaoweiandy</author><pubDate>Fri, 07 Jan 2022 23:26:53 +0800</pubDate><description><![CDATA[今天我们来聊一下线程间的通信。这里的通信指的是通俗意义上的“通个信儿”或者“通个气儿”，不是说要传递什么数据，更多的含义是“通知对方”。

我们现在来做一个2个动物参与的小游戏，在这里两个动物分别是猫和狗。先让猫跑10步，然后狗才能跑步，也是跑10步。要注意的是: 当猫10步还未跑完的期间，狗决不能跑动，只有当第1个猫把10步跑完后，狗才能开始跑，也是跑10步。我们用代码如何来模拟这个过程呢？我们简单的执行2个for循环便是：




package testFuture;

public class Th]]></description><category></category></item><item><title><![CDATA[搭载rtmp直播服务器]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/120685531</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/120685531</guid><author>gaoxiaoweiandy</author><pubDate>Mon, 11 Oct 2021 21:33:54 +0800</pubDate><description><![CDATA[这次我们搭建一个rtmp直播服务器，用于电脑或手机直播推流到服务器，然后其他终端如电脑或手机可以观看直播的视频画面。 我们这里用电脑录屏软件将实时录制的电脑屏幕画面直播给其它人看。总共需要3部分，第一，录屏软件录制电脑屏幕，并传递画面流到服务器； 第二，服务器rtmp搭建，应能接收来自录屏软件上传的画面；第三，视频播放器客户端能连接到rtmp服务器，接收rtmp服务器推送的视频流，从而可实时观看第一部分录屏软件的实时画面。这里最核心的就是第二部分，搭建rtmp服务器。



1.下载ngin...]]></description><category></category></item><item><title><![CDATA[cmake编译NDK初体验]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/119856484</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/119856484</guid><author>gaoxiaoweiandy</author><pubDate>Thu, 02 Sep 2021 22:12:39 +0800</pubDate><description><![CDATA[本文用一个demo验证AndroidStudio如何编译生成一个C++动态库文件（so文件）给Java应用层使用。然后这个so库内部又如何调用一个预有so库中的C语言函数。

1. 新建一个NDK工程

1.1 新建一个android studio Native C++工程





在main/cpp目录下默认有一个native-lib.cpp，还有一个CMakeList.txt文件（编译脚本），目录下默认有一个native-lib

#include &lt;jni.h&gt;
#...]]></description><category></category></item><item><title><![CDATA[线程同步工具Exchanger]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116857518</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116857518</guid><author>gaoxiaoweiandy</author><pubDate>Mon, 02 Aug 2021 09:50:30 +0800</pubDate><description><![CDATA[package cn.itcast.heima2;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExchangerTest {

 public static void main(String[] args) {
  ExecutorService service...]]></description><category></category></item><item><title><![CDATA[Android事件分发]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/118379923</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/118379923</guid><author>gaoxiaoweiandy</author><pubDate>Mon, 02 Aug 2021 09:49:36 +0800</pubDate><description><![CDATA[梳理androidUI事件分发流程，解决appUI事件冲突问题：

当一个大按钮作为背景，上面放一个小按钮，这时点击小按钮，小按钮是否会响应单击事件？

答案：有可能背景响应了 单击事件，而让你的预期大跌眼镜。
这里简单做以下笔记：

假设背景容器布局是RelativeLayout，上面有一个Button。
OnInterceptTouchEvent :  RelativeLayout容器布局特有的事件分发函数
onTouchListener 接口的onTouch函数
onTouchEvent
onDi..]]></description><category></category></item><item><title><![CDATA[用BlockQueue实现线程间的通信，子线程执行完了主线程执行，主线程执行完了子线程执行]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116861515</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116861515</guid><author>gaoxiaoweiandy</author><pubDate>Mon, 02 Aug 2021 09:48:13 +0800</pubDate><description><![CDATA[package cn.itcast.heima2;

import java.util.Collections;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class BlockingQueueCommunication {

 /**
  *...]]></description><category></category></item><item><title><![CDATA[Hashmap与HashSet的关系]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/118058250</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/118058250</guid><author>gaoxiaoweiandy</author><pubDate>Sat, 19 Jun 2021 19:49:29 +0800</pubDate><description><![CDATA[Hashset内部是 由Hashmap构造的，只用到了Hashmap的key。

见Hashset的源码：


public class HashSet&lt;E&gt;
    extends AbstractSet&lt;E&gt;
    implements Set&lt;E&gt;, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;

    priva]]></description><category></category></item><item><title><![CDATA[BlockQueue阻塞队列实现之前的消费者生产者模式condition]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116861474</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116861474</guid><author>gaoxiaoweiandy</author><pubDate>Sat, 19 Jun 2021 19:21:44 +0800</pubDate><description><![CDATA[package testFuture;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueTest {
 public static void main(String[] args) {
  final BlockingQueue queue = new ArrayBlockingQueue(3);
 ...]]></description><category></category></item><item><title><![CDATA[线程工具Semaphore]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116856627</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116856627</guid><author>gaoxiaoweiandy</author><pubDate>Sat, 15 May 2021 17:34:58 +0800</pubDate><description><![CDATA[Semaphore信号灯，也是实现多线程间互斥的。多个线程只有拿到了这盏灯，才能执行下面的代码，相当于lock、sychronized； 当一个线程拿到了这盏灯后，其它线程将暂停等待，直到这个线程执行完毕释放灯。当然信号灯可以有多盏灯，如有3盏灯，然后10个线程去执行代码，这期间只能有3个线程拿到灯，可以执行。当有线程释放了1个灯后，其它7个线程当中才能有一个线程冲过去抢到灯。

示例代码如下：

package cn.itcast.heima2;

import java.util.concurrent.]]></description><category></category></item><item><title><![CDATA[线程工具CyclicBarrier]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116372640</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116372640</guid><author>gaoxiaoweiandy</author><pubDate>Sat, 15 May 2021 17:12:11 +0800</pubDate><description><![CDATA[package testFuture;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CyclicBarrierTest {

 public static void main(String[] args) {
  ExecutorService servi...]]></description><category></category></item><item><title><![CDATA[一个经典的多线程condition使用实例代码，请评论]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116355152</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116355152</guid><author>gaoxiaoweiandy</author><pubDate>Sun, 02 May 2021 17:20:50 +0800</pubDate><description><![CDATA[class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull  = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throw]]></description><category></category></item><item><title><![CDATA[线程-读写锁。]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116099251</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116099251</guid><author>gaoxiaoweiandy</author><pubDate>Sun, 02 May 2021 15:55:16 +0800</pubDate><description><![CDATA[读写锁。我们上次温习了synchronized与Lock.我们遗留了一个问题，就是想让读读不互斥，因为多线程同时读取数据并不会破坏数据。如果能实现读读不用互斥，那将大大提升了多线程读性能。于是我们引入了读写锁ReentrantReadWriteLock。ReentrantReadWriteLock可以专门创建一个读锁和写锁。读锁：读读不互斥，但是读写互斥。 写锁：不但读写互斥，而且写写也互斥。

创建一个读写锁

 ReadWriteLock rwl = new ReentrantReadWriteLoc.]]></description><category></category></item><item><title><![CDATA[线程Lock]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116096384</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/116096384</guid><author>gaoxiaoweiandy</author><pubDate>Sat, 24 Apr 2021 17:30:19 +0800</pubDate><description><![CDATA[我们之前学习了synchronized，今天来介绍一下lock。lock与synchronized一样都是为了多线程在竞争公共资源时，能不发生冲突，就是一个线程获取了锁，就去执行代码块，其它线程只能等待第一个线程执行完同步代码块，才能有机会获取到synchronized锁对象。

 lock与synchronized最大的区别是，lock锁的释放需要程序员手动调用unlock,一般放在要同步的代码的最后调用unlock，或者try..catch..finally中的finally里调用unlock。当然，.]]></description><category></category></item><item><title><![CDATA[Callable与Futrue.get()等待线程执行完毕]]></title><link>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/115799872</link><guid>https://blog.youkuaiyun.com/gaoxiaoweiandy/article/details/115799872</guid><author>gaoxiaoweiandy</author><pubDate>Sat, 17 Apr 2021 19:35:07 +0800</pubDate><description><![CDATA[1. 等待一个子线程执行完毕


public static void main(String[] args) {
		ExecutorService threadPool =  Executors.newSingleThreadExecutor();
		Future&lt;String&gt; future =
			threadPool.submit(
				new Callable&lt;String&gt;() {
					public String call() throws Excepti]]></description><category></category></item></channel></rss>