学校网站建设主要成绩,广州做网站建设的公司,防止wordpress目录显示,网站制作的一般过程为什么需要多线程进行开发#xff1f;多线程不管是嵌入式系统RTOS#xff0c;Linux#xff0c;还是应用开发#xff0c;中间件开发#xff0c;都是必不可少的#xff0c;做一个技术的时候#xff0c;如果能做到举一反三#xff0c;下次使用的时候不会再遇到坑#xff… 为什么需要多线程进行开发多线程不管是嵌入式系统RTOSLinux还是应用开发中间件开发都是必不可少的做一个技术的时候如果能做到举一反三下次使用的时候不会再遇到坑我这次给出的例子是Android 的多线程开发。如何使用一个线程在Android 应用程序里面如何使用一个线程呢?直接看下面的代码代码不是很多如果需要用的话直接摘抄过去就好了。//定义一个线程private SendThread mSendThread null;/** * 线程实体 */private class SendThread extends Thread{ public void run() { }}//实例化线程if (mSendThread null){ mSendThread new SendThread();}//启动线程mSendThread.start();多次调用start是同一个堆栈空间吗如果只new了一次线程多次start会出现怎么样的情况呢android 线程start的函数原型如下public synchronized void start() { /** * This method is not invoked for the main method thread or system * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state NEW. */ // Android-changed: throw if started is true if (threadStatus ! 0 || started) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the groups list of threads * and the groups unstarted count can be decremented. */ group.add(this); started false; try { nativeCreate(this, stackSize, daemon); started true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }然后我做了下面的一个代码实验/** * 发送线程实体 */private class SendThread extends Thread{ int testCount 20; public void run() { while(testCount 0) { Log.d(TAG,testCount:testCount); testCount --; } }}//实例化线程if (mSendThread null){ mSendThread new SendThread();}//启动线程mSendThread.start();mSendThread.start();结果输出如下D/ttyusb: testCount:20D/ttyusb: testCount:20D/ttyusb: testCount:19D/ttyusb: testCount:19D/ttyusb: testCount:18D/ttyusb: testCount:18D/ttyusb: testCount:17D/ttyusb: testCount:16D/ttyusb: testCount:17D/ttyusb: testCount:15D/ttyusb: testCount:16D/ttyusb: testCount:14D/ttyusb: testCount:15D/ttyusb: testCount:13D/ttyusb: testCount:14D/ttyusb: testCount:12D/ttyusb: testCount:13D/ttyusb: testCount:11D/ttyusb: testCount:12D/ttyusb: testCount:10D/ttyusb: testCount:9D/ttyusb: testCount:11D/ttyusb: testCount:8D/ttyusb: testCount:10D/ttyusb: testCount:7D/ttyusb: testCount:9D/ttyusb: testCount:6D/ttyusb: testCount:5D/ttyusb: testCount:8D/ttyusb: testCount:4D/ttyusb: testCount:7D/ttyusb: testCount:3D/ttyusb: testCount:6D/ttyusb: testCount:2D/ttyusb: testCount:1D/ttyusb: testCount:5D/ttyusb: testCount:4D/ttyusb: testCount:3D/ttyusb: testCount:2D/ttyusb: testCount:1可以看出线程每次start后他们使用的堆栈空间是不相同的。在双线程里面使用互斥锁使用互斥锁的情况非常普遍但是新手写代码肯定会有道意想不到的问题我就是那个新手我就遇到了那个意想不到的问题。给出下面一段代码/** * 线程实体 */ public class SendThread extends Thread { public void run() { isStart true; for(int i0;i20;i) { lock.lock(); successCount i; lock.unlock(); Log.d(TAG, Write:testCount: successCount); } isStart false; } } /** * 接收数据的线程 */ public class ReceiveThread extends Thread { Override public void run() { int testCount 20; super.run(); //条件判断只要条件为true则一直执行这个线程 while (isStart true) { testCount successCount; Log.d(TAG, Read:testCount: testCount); } } }代码执行的流程大概如下代码输出03-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:003-08 11:41:35.383 14866-14866/? D/TEST: 启动线程完成03-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:103-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:203-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:103-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:303-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:303-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:403-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:403-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:503-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:503-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:603-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:603-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:703-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:703-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:803-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:803-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:903-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:903-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1003-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:1003-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1103-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:1103-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1203-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:1203-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1303-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:1303-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1403-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:1403-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1503-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:1503-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1603-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:1603-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1703-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:1703-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1803-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:1803-08 11:41:35.383 14866-14906/? D/TEST: Write:testCount:1903-08 11:41:35.383 14866-14907/? D/TEST: Read:testCount:19上述代码问题我们希望的代码流程是我发送一个数据你就接收一个数据不能出现数据丢失的情况但是上面的日子来看接收数据是发生了丢失这样的情况如果在实际应用中是非常危险的。所以代码需要类似下面这样修改 /** * 线程实体 */ public class SendThread extends Thread { public void run() { isStart true; for(int i0;i20;i) { Log.d(TAG,开始写线程~); lock.lock(); successCount i; Log.d(TAG, 写数据:testCount: successCount); lock.unlock(); Log.d(TAG,写线程休眠~); sendTreadSleep(10); } isStart false; } } /** * 接收数据的线程 */ public class ReceiveThread extends Thread { Override public void run() { int testCount 20; super.run(); //条件判断只要条件为true则一直执行这个线程 while (isStart true) { Log.d(TAG,开始读线程~); lock.lock(); testCount successCount; Log.d(TAG, 读数据~:testCount: testCount); lock.unlock(); Log.d(TAG,读线程休眠~); receiveTreadSleep(5); } } }工程的Demo到时候在文末给出写线程在写完后就休眠10MS然后再到读线程执行加的日志非常方便大家观看两个线程之间的运行逻辑。日志输出如下 D/TEST: 启动线程完成 D/TEST: 开始写线程~ D/TEST: 写数据:testCount:0 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:0 D/TEST: 读线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:0 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:1 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:1 D/TEST: 读线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:1 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:2 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:2 D/TEST: 读线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:2 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:3 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:3 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 开始读线程~ D/TEST: 写数据:testCount:4 D/TEST: 写线程休眠~ D/TEST: 读数据~:testCount:4 D/TEST: 读线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:4 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:5 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:5 D/TEST: 读线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:5 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:6 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:6 D/TEST: 读线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:6 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:7 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:7 D/TEST: 读线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:7 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:8 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:8 D/TEST: 读线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:8 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:9 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:9 D/TEST: 读线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:9 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:10 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:10 D/TEST: 读线程休眠~grande.ttyusb.test0001/com.evergrande.ttyusb.test0001.MainActivity] connect: already connected (cur1 req1) D/TEST: 开始读线程~ D/TEST: 开始写线程~ D/TEST: 读数据~:testCount:10 D/TEST: 读线程休眠~ D/TEST: 写数据:testCount:11 D/TEST: 写线程休眠~ D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000 D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:11 D/TEST: 读线程休眠~ D/TEST: 开始写线程~ D/TEST: 写数据:testCount:12 D/TEST: 写线程休眠~ D/TEST: 开始读线程~ D/TEST: 读数据~:testCount:12使用synchronized来达到完成互斥synchronized修饰的方法可以让两个方法之间完成互斥比如写和读互斥写和写互斥读和读互斥都可以用这个方法。使用代码如下 /** * 线程实体 */ public class SendThread extends Thread { public void run() { isStart true; for(int i0;i10;i) { Log.d(TAG,开始写线程~); mDataValue.setData(i); Log.d(TAG, 写数据:testCount: successCount); Log.d(TAG,写线程休眠~); sendTreadSleep(10); } isStart false; } } /** * 接收数据的线程 */ public class ReceiveThread extends Thread { Override public void run() { int testCount 20; Log.d(TAG,s开始读线程~); super.run(); //条件判断只要条件为true则一直执行这个线程 while (isStart true) { Log.d(TAG,开始读线程~); testCount mDataValue.getData(); Log.d(TAG, 读数据~:testCount: testCount); Log.d(TAG,读线程休眠~); receiveTreadSleep(5); } } } /** * 发送线程延迟 * param millis 毫秒 */ private void sendTreadSleep(int millis) { try{ mSendThread.sleep(millis); } catch (Exception e) { e.printStackTrace(); } } /** * 接收线程延迟 * param millis 毫秒 */ private void receiveTreadSleep(int millis) { try{ mReceiveThread.sleep(millis); } catch (Exception e) { e.printStackTrace(); } } private class DataValue{ private synchronized void setData(int value){ Log.d(TAG,设置数据~setData); successCount value; } private synchronized int getData(){ Log.d(TAG,获取数据~getData); return successCount; } }读写锁ReentrantReadWriteLock上面是使用互斥锁这里介绍一个读写锁也是用来完成互斥的。使用代码如下 /** * 线程实体 */ public class SendThread extends Thread { public void run() { isStart true; for(int i0;i10;i) { mrwDataValue.setData(i); Log.d(TAG,Thread.currentThread().getName() 写休眠); sendTreadSleep(10); } isStart false; } } /** * 接收数据的线程 */ public class ReceiveThread extends Thread { Override public void run() { int testCount 20; Log.d(TAG,s开始读线程~); super.run(); //条件判断只要条件为true则一直执行这个线程 while (isStart true) { mrwDataValue.getData(); Log.d(TAG,Thread.currentThread().getName() 读休眠); receiveTreadSleep(5); } } } /* * 使用读写锁完成互斥ReadWriteLock */ private class rwDataValue{ private ReadWriteLock readWriteLock new ReentrantReadWriteLock(); private int Data; private void setData(int value){ readWriteLock.writeLock().lock(); try { Log.d(TAG, Thread.currentThread().getName() 写数据~setData:value); Data value; Thread.sleep(30); }catch (Exception i){ Log.e(TAG,error); }finally { readWriteLock.writeLock().unlock(); } } private void getData(){ readWriteLock.readLock().lock(); try { Log.d(TAG,Thread.currentThread().getName() 获取数据~getData Data); Thread.sleep(10); }catch (Exception i){ Log.e(TAG,error); }finally { readWriteLock.readLock().unlock(); } }参考https://blog.csdn.net/zy_style/article/details/53423877Demo 代码https://github.com/weiqifa0/androitdThread当你看到这里的时候说明你已经阅读完上面的内容不管怎样感谢您有心或者无意的关注和支持想获取学习1024G资料请点击状态栏公众号福利按钮