简书链接:android开发巩固java基础notifywait的妙用javaandroid测试以及翻出我之前2015年的有道云笔记供大家参考 文章字数:950,阅读全文大约需要3分钟 经常玩 测试类的都应该知道,android测试测试子线程的时候往往直接结束了,并没有看到日志打印,难道真的没法测试了吗?
其实不然,java的notify 和wait就可以派上用场啦! 在android test快结束的时候 synchronized锁进行等待即可.
有时候java基础还是很重要的啦,当然咯,很久没玩java 线程同步,可能全还给老师也是可以理解的.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package cn.qssq666.videotest; /** * Created by qssq on 2018/4/20 [email protected] */ public class WaitTest { @org.junit.Test public void waitAndNotify() { final Object lock = new Object(); new Thread(new Runnable() { int count = 0; @Override public void run() { while (count < 10) { try { Thread.sleep(1000); System.out.println("current :" + count); } catch (InterruptedException e) { e.printStackTrace(); } count++; } System.out.println("我是子线程:" + Thread.currentThread().getName()); System.out.println("调用notify start"); synchronized (lock) { lock.notify();//必须同步锁包裹才能进行调用 Exception in thread "Thread-0" java.lang.IllegalMonitorStateException } System.out.println("调用notify end"); } }).start(); System.out.println("即将进入线程等待"); synchronized (lock) { try { lock.wait(); // lock.wait(1000555); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("收到notify,退出等待"); } } }
那么打印的结果打印也应该可以猜到了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 即将进入线程等待 current :0 current :1 current :2 current :3 current :4 current :5 current :6 current :7 current :8 current :9 我是子线程:Thread-0 调用notify start 调用notify end 收到notify,退出等待
随便记录一下要添加的依赖
1 2 3 4 5 6 7 8 dependencies { androidTestCompile 'com.android.support.test:runner:0.4.1'//android测试 androidTestImplementation 'com.android.support.test:rules:0.4.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.1'//android测试 compile fileTree(include: ['*.jar'], dir: 'libs') testImplementation 'junit:junit:4.12' //java测试 }
最后我从有道云中找到了我2015年的笔记说实话我现在看的云里雾里,到底是那时候太菜,还是现在太菜忘记了所有???
线程和进程相关知识点 进程 就是运行的程序 线程 就是 进程 总的一个执行路径 多线程:一个进程中 有多个进行,多个执行路径可以执行多个任务代码 多线程的好处: 解决1个进程中可以执行多个任务 提高了资源利用率 多线的的坏处: 增加了cpu的负担, 降低了进程中线程的执行概率 容易引发线程安全问题 用同步锁 容易出现死锁现象 线程的创建方式有2中
1 继承Thread 重写run方法 new自身 继承了父类Thread的start() 所以直接new自身类().start()就可以启动线程
2 实现Runnable 实现run方法 把Runnable实现类传递给Thread类 new Thread(new 实现Runnable类()).start(); JAVA同步机制:
同步代码块 格式:
同步代码块注意事项 锁对象可以是任意对象,因为有隐式变量 可当锁
锁对象必须多个线程共享一个对象,要保证唯一
一个线程调用sleep方法 不会释放锁对象
如果当前代码没有存在线程安全问题,千万不要使用同步机制
否则会降低执行效率
同步函数 1、非静态函数的锁对象是this对象,静态函数锁对象是当前函数所属类的class对象 this.getClass 第二种: 直接填写指定文件 如 Person.Class 第三种:对象.getClass 另外获取自身对象 直接 this就可以死锁现象 线程和线程之间出现了互相等待对象资源的情况
代码笔记 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 package sernirolock1; // import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Demo { /** * @param args * 高级 不同线程池 实现 线程通信 * 本例使用lock 显式锁对象和condition 监视器实现了不同线程池 多线程通信 * 而用synchronized是无法实现的。 */ public static void main(String[] args) { Resource r = new Resource(); Lock l = new ReentrantLock(); Condition cCondition = l.newCondition(); Condition pCondition = l.newCondition(); new Producter("情迁的老婆", r, l, cCondition,pCondition).start(); new Customer("情迁", r, l, cCondition,pCondition).start(); } } class Resource { public String name; public int price; public boolean flag;// 真为已生产 public Lock lock; public Condition condition; } class Producter extends Thread { Resource resource; Lock lock; Condition cCondition; Condition pCondition; public Producter(Resource resource, Lock lock, Condition cCondition,Condition pCondition) { this.resource = resource; this.lock = lock; this.cCondition = cCondition; this.pCondition = pCondition; } /** * * @param name * @param resource * 被共享资源 * @param lock * 锁对象 */ public Producter(String name, Resource resource, Lock lock, Condition cCondition,Condition pCondition) { super(name); this.resource = resource; this.lock = lock; this.cCondition = cCondition; this.pCondition = pCondition; } @Override public void run() { int i = 0; while (true) { lock.lock(); if (!resource.flag) { if (i % 2 == 0) { resource.name = "自行车"; resource.price = 300; } else { resource.name = "摩托车"; resource.price = 1000; } System.out.println(this.getName() + "生产了价值" + resource.price + "元的" + resource.name); resource.flag = true; cCondition.signal();//我是生产发送信号给监视器->消费者线程 i++; } else { try { pCondition.await();//我是生产线程,没人消费我就暂时不生产 } catch (InterruptedException e) { // e.printStackTrace(); } } lock.unlock(); } } } class Customer extends Thread { Resource resource; Lock lock; Condition cCondition; Condition pCondition; public Customer(Resource resource, Lock lock, Condition cCondition,Condition pCondition) { this.resource = resource; this.lock = lock; this.cCondition = cCondition; this.pCondition = pCondition; } public Customer(String name, Resource resource, Lock lock, Condition cCondition,Condition pCondition) { super(name); this.resource = resource; this.lock = lock; this.cCondition = cCondition; this.pCondition = pCondition; } @Override public void run() { while (true) { lock.lock(); if (resource.flag) { System.out.println(this.getName() + "消费了价值" + resource.price + "元的" + resource.name); resource.flag = false; pCondition.signal();//我是消费发送信号给监视器->生产者线程 } else { try { cCondition.await();//我是消费者线程,我已经消费完毕,我睡了哈 } catch (InterruptedException e) { // e.printStackTrace(); } } lock.unlock(); } } }