关键词:
背景用两个线程交替输出A-Z和1-26,即一个线程输出A-Z,另一个线程输出1-26
而且是交替形式
线程1输出A——线程二输出1
线程1输出B——线程二输出2
线程1输出C——线程二输出3
以此类推
分析
主要考察线程之间的通信,思路就是创建两个线程
在一个线程输出一个内容之后,自己进入阻塞,去唤醒另一个线程
另一个线程同样,输出一个内容之后,自己进入阻塞,去唤醒另一个线程
代码实现(一)
public class AlternateCover
public static void main(String[] args)
final char[] arrLetter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
final String[] arrNumber = "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";
threadRun(arrLetter, arrNumber);
private static void threadRun(char[] arrLetter,String[] arrNumber)
final Object lock = new Object();// 设置一个锁对象
// print arrNumber
new Thread(() ->
synchronized (lock)
for (String a : arrNumber)
System.out.print( a);
try
lock.notify();// 唤醒其他等待的线程 此处唤醒 arrLetter
lock.wait();// arrNumber自己进入等待 让出CPU资源和锁资源
catch (InterruptedException e)
e.printStackTrace();
lock.notify();
, "arrNumber ").start();
// print arrLetter
new Thread(() ->
synchronized (lock) // 获取对象锁
for (char a : arrLetter)
System.out.print(a);
try
lock.notify();// 唤醒其他等待的线程 此处唤醒 arrNumber
lock.wait();// arrLetter自己进入等待 让出CPU资源和锁资源
catch (InterruptedException e)
e.printStackTrace();
lock.notify();// 最后那个等待的线程需要被唤醒,否则程序无法结束
, "arrLetter ").start();
运行一下,确实实现了交替输出,但是多运行几次,就会发现问题
有时候是数字先输出,有时候是字母先输出
即两个线程谁先启动的顺序是不固定的
倘若试题中再加一句,必须要字母先输出,怎么办?
代码实现(二)
/**
* 交替掩护 必须保证大写字母先输出
*/
public class AlternateCover
public static volatile Boolean flg = false;// 谁先开始的标志 volatile修饰目的是让该值修改对所有线程可见,且防止指令重排序
public static void main(String[] args)
final char[] arrLetter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
final String[] arrNumber = "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";
threadRun(arrLetter, arrNumber);
private static void threadRun(char[] arrLetter,String[] arrNumber)
final Object lock = new Object();// 锁对象
// print arrLetter
new Thread(() ->
synchronized (lock)
if (!flg) // 如果flg是false 就将值设为true
flg = true;
for (char a : arrLetter)
System.out.print(a);// 输出内容
try
lock.notify();// 唤醒在等待的其他线程中的一个(此处也只有另一个)
lock.wait();// 自己进入等待 让出CPU资源和锁资源
catch (InterruptedException e)
e.printStackTrace();
lock.notify();// 最后那个等待的线程需要被唤醒,否则程序无法结束
, "arrLetter").start();
// print arrNumber
new Thread(() ->
synchronized (lock)
if (!flg)// 倘若是该线程先执行,那么flg次数还是false 就先等着
try
lock.wait();
catch (InterruptedException e)
e.printStackTrace();
for (String a : arrNumber)
System.out.print( a);
try
lock.notify();
lock.wait();
catch (InterruptedException e)
e.printStackTrace();
lock.notify();
, "arrNumber").start();
如此问题可以得到解决,但有更优(装)雅(B)的解决办法
CountDownLatch实现
/**
* 交替掩护 必须保证大写字母先输出
*/
public class AlternateCover
private static CountDownLatch count = new CountDownLatch(1);// 计数器容量为1
public static void main(String[] args)
final char[] arrLetter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
final String[] arrNumber = "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";
threadRun(arrLetter, arrNumber);
private static void threadRun(char[] arrLetter,String[] arrNumber)
final Object lock = new Object();
// print arrLetter
new Thread(() ->
synchronized (lock) // 获取对象锁
count.countDown();// 对计数器进行递减1操作,当计数器递减至0时,当前线程会去唤醒阻塞队列里的所有线程(只针对count)
for (char a : arrLetter)
System.out.print(a);
try
lock.notify();// 唤醒其他等待的线程 此处唤醒 arrNumber
lock.wait();// arrLetter自己进入等待 让出CPU资源和锁资源
catch (InterruptedException e)
e.printStackTrace();
lock.notify();// 最后那个等待的线程需要被唤醒,否则程序无法结束
, "arrLetter ").start();
// print arrNumber
new Thread(() ->
synchronized (lock)
try
count.await();// 如果该线程先执行 阻塞当前线程,将当前线程加入阻塞队列
catch (InterruptedException e)
e.printStackTrace();
for (String a : arrNumber)
System.out.print( a);
try
lock.notify();// 唤醒其他等待的线程 此处唤醒 arrLetter
lock.wait();// arrNumber自己进入等待 让出CPU资源和锁资源
catch (InterruptedException e)
e.printStackTrace();
lock.notify();
, "arrNumber ").start();
结尾
以上就是synchronized实现两个线程交替运行的解法,欢迎留言交流
感谢看到最后的朋友,都看到最后了,点个赞再走啊,如有不对之处还请多多指正。
实现两个线程从0-100交替打印(代码片段)
...去实现0-100交替打印,大家无聊的话,可以瞅两眼。一、Synchronized实现:publicclassPrintNumberIncrInSynchronizedprivatestaticintnumber;privatestaticfinalObjectobject=newObject();publicstaticvoidmain( 查看详情
wait,notify实现两个线程交替打印
...assAddPrintprivatestaticObjecto=newObject();//锁publicvoidprint(flagf)synchronized(o)for(inti=1;i<50;i++)if(f.isShouldRun())//shouldRun=false;f.setShouldRun(false);o.notify();if(i<49) 查看详情
两个线程交替打印(代码片段)
使用同一个Runnable对象加锁打印publicclassPringThreadimplementsRunnableinti=1;@Overridepublicvoidrun()while(true)synchronized(this)notify();if(i<=100)System.out.println(Thread.currentThread(). 查看详情
两个线程交替打印1到100
packagecom.zs.thread;importjava.util.concurrent.TimeUnit;publicclassSumThread{publicvoidone()throwsInterruptedException{synchronized(this){booleanflag=true;while(flag){for(inti=1;i<=99;i+=2){System 查看详情
多线程交替打印abc的多种实现方法
...;并且实现交替打印,即按照ABCABCABC的顺序打印。二、Synchronized同步法1、基本思路使用同步块和wait、notify的方法控制三个线程的执行次序。具体方法如下:从大 查看详情
两个线程交替打印数字(看了就懂版)
/***@description:*@author:*@create:2020-11-1521:12**/publicclassSwapThreadstaticclassMythread1extendsThreadpublicvoidrun()synchronized(SwapThread.class)for(inti=2;i<1000;i+=2)System.out.printl 查看详情
面试题:用程序实现两个线程交替打印0~100的奇偶数
...知识,但是面试官抛一个问题过来,短时间内可能想不出如何使用这些知识来解决这个具体的问题。其实这个问题考察的知识点并不难,但是如果准备的面试的时候没有看过这道题,一时间还是比较难想出解决方案来的,而且这... 查看详情
synchronized的底层实现原理(代码片段)
1.JDK1.6对synchronized做的优化:传统的锁(也就是下文要说的重量级锁)依赖于系统的同步函数,在linux上使用mutex互斥锁,这些同步函数都涉及到用户态和内核态的切换、进程的上下文切换,成本较高。对于加了s... 查看详情
线程交替运行
packagethreadtest;publicclassTest1{/**两个线程,一个打印1-100的奇数,一个打印1-100的偶数;要求:线程1打印5个之后,线程2开始打印,线程2打印5个之后,线程1再开始打印,以此循环。*/privatestaticintstate=1;privatestaticintnum1=1;privatestaticintn... 查看详情
请问这个java的thread程序,为啥没有出现两个线程交替运行?
publicclassThreadDemo_2publicstaticvoidmain(String[]args)TestThreadt=newTestThread();newThread(t).start();for(inti=0;i<10;i++)System.out.println("mian线程在运行!");classTestThreadimplementsRunnablepublicvoidrun()for(inti=0;i<10;i++)System.out.println("TestThread线程在... 查看详情
多线程交替打印abc的多种实现方法
...;并且实现交替打印,即按照ABCABCABC的顺序打印。二、Synchronized同步法1、基本思路使用同步块和wait、notify的方法控制三个线程的执行次序。具体方法如下:从大的方向上来讲,该问题为三线程间的同步唤醒操作,... 查看详情
synchronized同步方法的八种使用场景
...的锁,不能形成两个线程竞争一把锁的局势,所以这时,synchronized修饰的方法method()和不用synchronized修饰的效果一样(不信去把synchronized关键字去掉,运行结果一样),所以此时的method()只是个普通方法。若要使锁生效,只需将me... 查看详情
c++实现两个线程交替打印奇偶数(代码片段)
#include<iostream>#include<mutex>#include<thread>#include<condition_variable>#include<Windows.h>usingnamespacestd;mutexmut;condition_variablecond1,cond2;intg_nums=1;/ 查看详情
两个线程交替打印1-99(代码片段)
参考https://github.com/crossoverJie/JCSprout/blob/master/src/main/java/com/crossoverjie/actual/TwoThread.java从线程方面实现交替打印。publicclassTestvolatilebooleanisEven=false;@org.junit.Testpublicvoidtestfda()thr 查看详情
经典笔试题:两个线程交替打印奇偶数(代码片段)
一、采用对象的wait()notify()方法实现packagecom.gaopeng.programming;importjava.util.concurrent.TimeUnit;/***经典笔试题:交替打印奇偶数采用对象的wait()notify()方法实现**@authorgaopeng**/publicclassOddEvenThreadprivatestaticvolatileInt 查看详情
synchronized底层如何实现?啥是锁的升级,降级
参考技术Asynchronized底层如何实现?什么是锁的升级,降级。操作系统分为用户态和内核态,应用级别的程序会运行在用户态,不能访问硬件,操作系统内核的程序会运行在内核态,可以直接访问硬件。synchronized是重量级锁,运... 查看详情
阿里真题:线程交叉打印(代码片段)
...CyclicBarrier篱栅、回环屏障、Semaphore信号灯、ReentrantLock、synchronized、AtomicBoolean无锁cas。全部都已经在leetCode提交通过关于这些关键字的原理解释点我代码如下:ReentrantLock方案/***方案3Reentran 查看详情
synchronized(代码片段)
1.什么是synchronizedsynchronized 关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、D等)正在用这个方法(或者该类的其他同步方法),有的话要等正在使用synch... 查看详情