synchronized处理线程wait() 和notifyAll() 时,同步代码块中不要包含Thread.sleep(5)语句:
1 package com.csizg.test; 2 3 4 import java.util.ArrayList; 5 import java.util.List; 6 7 /** 8 * 与芯片交互线程 9 */ 10 public class SpiQueue implements Runnable { 11 12 private static final String TAG = SpiQueue.class.getSimpleName(); 13 14 private static final byte INIT = 0;// 初始化 15 private static final byte RUNNING = 1;// 执行中 16 private static final byte WITING = 2;// 暂停等待中 17 private static final byte DONE = 3;// 结束 18 19 private byte state = INIT;// 执行状态 20 21 private static SpiQueue spiQueue = null; 22 private boolean isTalking = false; 23 24 private SpiQueue() { 25 26 } 27 28 public static SpiQueue getSpiQueue() { 29 if (spiQueue == null) { 30 spiQueue = new SpiQueue(); 31 } 32 return spiQueue; 33 } 34 35 private Thread thread; 36 private List<SpiTask> tasks = new ArrayList<>(); 37 38 @Override 39 public void run() { 40 state = RUNNING; 41 while (state != DONE) { 42 43 SpiTask currentTask = getNextTask(); 44 if (currentTask == null) { 45 if (isTalking) { 46 System.out.println(TAG + " run " + "no task todo begin to sleep"); 47 try { 48 Thread.sleep(5); 49 } catch (InterruptedException e) { 50 e.printStackTrace(); 51 } 52 continue; 53 } else { 54 System.out.println(TAG + " run " + "no task todo begin to waiting"); 55 synchronized (this) { 56 try { 57 state = WITING; 58 wait(); 59 } catch (InterruptedException e) { 60 e.printStackTrace(); 61 } 62 } 63 } 64 } else { 65 try { 66 Thread.sleep(10); 67 } catch (InterruptedException e) { 68 e.printStackTrace(); 69 } 70 System.out.println(TAG + " run " + "currentTask = " + currentTask.toString()); 71 } 72 73 } 74 75 } 76 77 private synchronized SpiTask getNextTask() { 78 System.out.println(TAG + " getNextTask " + "tasks.size() = " + tasks.size()); 79 if (tasks.size() > 0) { 80 SpiTask task = tasks.remove(0); 81 return task; 82 } 83 return null; 84 } 85 86 public synchronized void addTask(SpiTask task) { 87 System.out.println(TAG + " addTask " + "tasks.size() = " + tasks.size() + ", new task : " + task.getCode()); 88 if (state == DONE) { 89 System.out.println(TAG + " addTask " + "Thread is DONE : task : " + task.getCode()); 90 return; 91 } 92 tasks.add(task); 93 if (state != RUNNING) { 94 synchronized (this) { 95 state = RUNNING; 96 System.out.println(TAG + " addTask notifyAll "); 97 notifyAll(); 98 } 99 } 100 } 101 102 public synchronized void start() { 103 System.out.println(TAG + " start " + "state = " + state); 104 if (state == RUNNING || state == WITING) { 105 return; 106 } 107 state = INIT; 108 // 运行本线程 109 tasks.clear(); 110 if (thread != null) { 111 thread.interrupt(); 112 } 113 thread = new Thread(this); 114 thread.start(); 115 } 116 117 118 public synchronized void stop() { 119 state = DONE; 120 tasks.clear(); 121 isTalking = false; 122 synchronized (this) { 123 notifyAll(); 124 } 125 } 126 127 public void setTalking(boolean isTalking) { 128 this.isTalking = isTalking; 129 } 130 }
结果花费1.6s;
1 package com.csizg.test; 2 3 4 import java.util.ArrayList; 5 import java.util.List; 6 7 /** 8 * 与芯片交互线程 9 */ 10 public class SpiQueue implements Runnable { 11 12 private static final String TAG = SpiQueue.class.getSimpleName(); 13 14 private static final byte INIT = 0;// 初始化 15 private static final byte RUNNING = 1;// 执行中 16 private static final byte WITING = 2;// 暂停等待中 17 private static final byte DONE = 3;// 结束 18 19 private byte state = INIT;// 执行状态 20 21 private static SpiQueue spiQueue = null; 22 private boolean isTalking = false; 23 24 private SpiQueue() { 25 26 } 27 28 public static SpiQueue getSpiQueue() { 29 if (spiQueue == null) { 30 spiQueue = new SpiQueue(); 31 } 32 return spiQueue; 33 } 34 35 private Thread thread; 36 private List<SpiTask> tasks = new ArrayList<>(); 37 38 @Override 39 public void run() { 40 state = RUNNING; 41 while (state != DONE) { 42 synchronized (this) { 43 SpiTask currentTask = getNextTask(); 44 if (currentTask == null) { 45 if (isTalking) { 46 System.out.println(TAG + " run " + "no task todo begin to sleep"); 47 try { 48 Thread.sleep(5); 49 } catch (InterruptedException e) { 50 e.printStackTrace(); 51 } 52 continue; 53 } else { 54 System.out.println(TAG + " run " + "no task todo begin to waiting"); 55 try { 56 state = WITING; 57 wait(); 58 } catch (InterruptedException e) { 59 e.printStackTrace(); 60 } 61 } 62 } else { 63 try { 64 Thread.sleep(10); 65 } catch (InterruptedException e) { 66 e.printStackTrace(); 67 } 68 System.out.println(TAG + " run " + "currentTask = " + currentTask.toString()); 69 } 70 } 71 } 72 73 } 74 75 private synchronized SpiTask getNextTask() { 76 System.out.println(TAG + " getNextTask " + "tasks.size() = " + tasks.size()); 77 if (tasks.size() > 0) { 78 SpiTask task = tasks.remove(0); 79 return task; 80 } 81 return null; 82 } 83 84 public synchronized void addTask(SpiTask task) { 85 System.out.println(TAG + " addTask " + "tasks.size() = " + tasks.size() + ", new task : " + task.getCode()); 86 if (state == DONE) { 87 System.out.println(TAG + " addTask " + "Thread is DONE : task : " + task.getCode()); 88 return; 89 } 90 tasks.add(task); 91 if (state != RUNNING) { 92 synchronized (this) { 93 state = RUNNING; 94 System.out.println(TAG + " addTask notifyAll "); 95 notifyAll(); 96 } 97 } 98 } 99 100 public synchronized void start() { 101 System.out.println(TAG + " start " + "state = " + state); 102 if (state == RUNNING || state == WITING) { 103 return; 104 } 105 state = INIT; 106 // 运行本线程 107 tasks.clear(); 108 if (thread != null) { 109 thread.interrupt(); 110 } 111 thread = new Thread(this); 112 thread.start(); 113 } 114 115 116 public synchronized void stop() { 117 state = DONE; 118 tasks.clear(); 119 isTalking = false; 120 synchronized (this) { 121 notifyAll(); 122 } 123 } 124 125 public void setTalking(boolean isTalking) { 126 this.isTalking = isTalking; 127 } 128 }
花费时间11.2s;
测试调用代码:
1 public void test() { 2 SpiTask spiTask = null; 3 for (int i = 0; i < 30; i++) { 4 spiTask = new SpiTask("Thread --- " + i, "" + i); 5 if (i > 6) { 6 SpiQueue.getSpiQueue().setTalking(true); 7 } 8 SpiQueue.getSpiQueue().addTask(spiTask); 9 try { 10 Thread.sleep(20); 11 } catch (InterruptedException e) { 12 e.printStackTrace(); 13 } 14 } 15 SpiQueue.getSpiQueue().setTalking(false); 16 }
当synchronized同步代码块中去掉Thread.sleep(5)时,结果一致,都是1.6s左右。