Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
线程与线程的通信机制_线程安全的类有哪些,希望能够帮助你!!!。
线程间通信其实就是多个线程在操作同一个资源时,多个线程之间不断切换执行时所发出的信号。例如:需要创建两个线程,一条线程只打印1-26的数字,另一条只打印A-Z的字母,最终打印结果为1A2B3C4D…26Z时,这时就需要使用线程之间的通信来交替完成。
首先创建一个共用的线程池去管理和运行这两个线程:
public class ThreadPoolTest { // 创建一个定长的线程池 private static final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2); // 创建一个数字的数组 public static String[] buildNoArr(int max) { String[] noArr = new String[max]; for(int i=0;i<max;i++){ noArr[i] = Integer.toString(i+1); } return noArr; } // 创建一个字母的数组 public static String[] buildCharArr(int max) { String[] charArr = new String[max]; int tmp = 65; for(int i=0;i<max;i++){ charArr[i] = String.valueOf((char)(tmp+i)); } return charArr; } // 提供公用的打印字符的方法 public static void printStr(String... input){ if(input==null) return; for(String each:input){ System.out.print(each); } } // 提交线程的方法 public void run(Runnable r){ fixedThreadPool.submit(r); } // 关闭线程的方法 public void shutdown(){ fixedThreadPool.shutdown(); } }
public class ThreadTest1 { // 创建线程池对象 ThreadPoolTest poolTest = new ThreadPoolTest(); // 创建一个空的集合对象用来存放打印的字符,并用该对象生成一个对象锁 private final List<String> list = new ArrayList<>(); public Runnable newThreadOne() { final String[] noArr = poolTest.buildNoArr(26); return new Runnable() { public void run() { for (int i = 0; i < noArr.length; i++) { synchronized (list) { if (list.size() % 2 == 1) { try { list.wait(); //调用该锁对象的wait()方法,使当前线程进入等待状态,该线程后面的逻辑暂停执行 } catch (InterruptedException e) { e.printStackTrace(); } } poolTest.printStr(noArr[i]); list.add(noArr[i]); list.notify(); //调用该锁对象的notify()方法,此时会唤醒newThreadTwo线程,使newThreadTwo线程进入就绪状态,当newThreadTwo重新获取到cup时,则继续从上次暂停的代码处往下执行 } } } }; } public Runnable newThreadTwo() { final String[] charArr = poolTest.buildCharArr(26); return new Runnable() { public void run() { for (int i = 0; i < charArr.length; i++) { synchronized (list) { if (list.size() % 2 == 0) { try { list.wait(); //调用该锁对象的wait()方法,使当前线程进入等待状态,该线程后面的逻辑暂停执行 } catch (InterruptedException e) { e.printStackTrace(); } } poolTest.printStr(charArr[i]); list.add(charArr[i]); list.notify();//调用该锁对象的notify()方法,此时会唤醒newThreadOne线程,使newThreadOne线程进入就绪状态,当newThreadOne重新获取到cup时,则继续从上次暂停的代码处往下执行 } } } }; } // 测试 public static void main(String args[]) { ThreadTest1 three = new ThreadTest1(); ThreadPoolTest poolTest = new ThreadPoolTest(); poolTest.run(three.newThreadOne()); poolTest.run(three.newThreadTwo()); poolTest.shutdown(); } }
public class ThreadTest2 { static volatile int value = 1; int one = 0; int two = 0; ThreadPoolTest poolTest = new ThreadPoolTest(); public Runnable newThreadOne() { final String[] noArr = poolTest.buildNoArr(26); return new Runnable() { public void run() { while (true) { if (value == 1 && one < noArr.length) { poolTest.printStr(noArr[one]); one++; value = 2; } } } }; } public Runnable newThreadTwo() { final String[] charArr = poolTest.buildCharArr(26); return new Runnable() { public void run() { while (true) { if (value == 2 && two < charArr.length) { poolTest.printStr(charArr[two]); two++; value = 1; } } } }; } public static void main(String args[]) { ThreadTest2 three = new ThreadTest2(); ThreadPoolTest poolTest = new ThreadPoolTest(); poolTest.run(three.newThreadOne()); poolTest.run(three.newThreadTwo()); poolTest.shutdown(); } }
public class ThreadTest3 { private static volatile int value = 1; private Lock lock = new ReentrantLock(true); private Condition condition = lock.newCondition(); ThreadPoolTest poolTest = new ThreadPoolTest(); public Runnable newThreadOne() { final String[] noArr = poolTest.buildNoArr(26); return new Runnable() { public void run() { for (int i = 0; i < noArr.length; i++) { try { lock.lock(); //newThreadOne线程获取锁 if (value == 2) { condition.await(); // newThreadOne线程进入等待阻塞 } poolTest.printStr(noArr[i]); value = 2; condition.signal(); // 唤醒调用condition.await()进入阻塞的线程 } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); // 手动释放锁 } } } }; } public Runnable newThreadTwo() { final String[] charArr = poolTest.buildCharArr(26); return new Runnable() { public void run() { for (int i = 0; i < charArr.length; i++) { try { lock.lock(); // newThreadTwo线程获取锁 if (value == 1) { condition.await(); // newThreadTwo线程进入等待阻塞 } poolTest.printStr(charArr[i]); value = 1; condition.signal(); // 唤醒调用condition.await()进入阻塞的线程 } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); // 手动释放锁 } } } }; } public static void main(String args[]) { ThreadTest3 three = new ThreadTest3(); ThreadPoolTest poolTest = new ThreadPoolTest(); poolTest.run(three.newThreadOne()); poolTest.run(three.newThreadTwo()); poolTest.shutdown(); } }
public class ThreadTest4 { private AtomicInteger value = new AtomicInteger(1); int one = 0; int two = 0; ThreadPoolTest poolTest = new ThreadPoolTest(); public Runnable newThreadOne() { final String[] noArr = poolTest.buildNoArr(26); return new Runnable() { public void run() { while (true) { if (value.get() == 1 && one < noArr.length) { poolTest.printStr(noArr[one]); one++; value.set(2); } } } }; } public Runnable newThreadTwo() { final String[] charArr = poolTest.buildCharArr(26); return new Runnable() { public void run() { while (true) { if (value.get() == 2 && two < charArr.length) { poolTest.printStr(charArr[two]); two++; value.set(1); } } } }; } public static void main(String args[]) { ThreadTest4 three = new ThreadTest4(); ThreadPoolTest poolTest = new ThreadPoolTest(); poolTest.run(three.newThreadOne()); poolTest.run(three.newThreadTwo()); poolTest.shutdown(); } }
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章