创建两个线程,其中一个输出1-52,另外一个输出A-Z。输出格式要求:12A 34B 56C 78D 依次类推
2019-02-18 19:28
162 查看
前言
个人观点:线程同步为javaSE中最绕的部分,本文结合内部类,以可重入锁,Synchronized两种方式给大家形象展示了两种风格的迥异之处,该题为线程面试经典题型,希望对即将参加面试广大码农朋友有所帮助!!!
如有错误欢迎再评论区指正;
1 ReentrantLock实现
创建两个线程,其中一个输出1-52,另外一个输出A-Z。输出格式要求:12A 34B 56C 78D 依次类推
提示:定义一个类,其中定义两个方法,第一个方法用于输出数字,方法实现首先使用lock.lock加锁,并输出数字,当输出的数字为偶数时,使用condition.signalAll唤醒其他线程,并使用condition.await让当前线程进入等待队列;第二个方法用于输出字母,方法实现手续使用lock.lock加锁,并输出字母,每输出一个字母,使用condition.signalAll唤醒其他线程,并使用condition.await让当前线程进入等待队列。
注意:方法执行结束后必须使用lock.unlock释放锁标记。condition.await的调用必须有边界判断,避免线程锁死,无法执行。
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Test2 { public static void main(String[] args) { ReentrantLock r1=new ReentrantLock(); //定义一个互斥锁类型 Condition c = r1.newCondition();//定义一个字母锁条件 Condition c2 = r1.newCondition();//定义一个数字锁条件 new Thread(new Runnable(){ public void run() { try{//逻辑严谨性,定义一个try finally,保证一定释放锁; r1.lock();//获取锁 for (int i = 1; i <=52; i++) { System.out.println(i+" "); if(i%2==0){ c.signalAll();//唤醒字母进程 try { c2.await();//让数字进程等待 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }finally{ r1.unlock();//释放锁 } } }).start(); new Thread(new Runnable(){ @Override public void run() { try{ r1.lock( 20000 ); for (int i = 0; i < 26; i++) { System.out.println((char)('A' + i) + " "); c2.signalAll(); try { if(i!=25){//最后一个字母不用进入等待状态 c.await(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }finally{ r1.unlock(); } } }).start(); } }
2 Synchronized锁实现(以下为2019.04.07更新)
创建两个线程,其中一个输出1-52,另外一个输出A-Z。输出格式要求:12A 34B 56C 78D 依次类推。
提示:
定义两个类,分别继承Thread或实现Runnable。其中一个类中的run方法用于输出数字,当输出数字为偶数时wait,进入等待队列,且使用notify唤醒其他线程;另一个类中输出字母,每输出一个字母后,wait进入等待队列,且使用notify唤醒其他线程。两个类的run方法都使用同步代码块,对同一个对象加锁。
public class Problem01 { public static void main(String[] args) { Object object = new Object(); new Thread(new Number(object)).start(); ; new Thread(new Character(object)).start(); ; } } class Number implements Runnable { private Object object; public Number(Object object) { this.object = object; } @Override public void run() { synchronized (object) { for (int i = 1; i < 53; i++) { if (i > 1 && i % 2 == 1) { System.out.print(" "); } System.out.print(i); if (i % 2 == 0) { // 先释放锁,唤醒其他线程,再使本线程阻塞 object.notifyAll(); try { object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } class Character implements Runnable { private Object object; public Character(Object object) { this.object = object; } @Override public void run() { synchronized (object) { for (char i = 'A'; i <= 'Z'; i++) { System.out.print(i); // 先释放锁,唤醒其他线程,再使本线程阻塞 object.notifyAll(); if (i < 'Z') { // 线程执行的最后一次不能堵塞,不然会一直堵塞下去。 try { object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }
相关文章推荐
- 写两个线程,一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。要求用线程间的通信
- 写两个线程,其中一个线程打印1-52,另一个打印A-Z,打印顺序为12A34B56C....5152Z
- 写两个线程,其中一个线程打印1-52,另一个打印A-Z,打印顺序为12A34B56C....5152Z。(《疯狂java讲义》第12章课后题一)
- 写两个线程,一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。要求用线程间的通信
- 5.编写一个程序,有两个类,其中类MAX中具有两个方法,方法名都是max,一个方法能够比较两个数的大小,另外一个方法能够比较三个数的大小。在另外一个类中创建对象,调用这两个方法,分别输出两组数:2、6
- 输入任意大小的三个整数,判断其中是否有两个奇数一个偶数。若是,则输出“YES”,不是则输出“NOT” (要求用条件表达式进行判断,不使用if语句)
- 写两个线程,一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z
- 写两个线程,一个线程打印1-52,另一个线程打印字母A-Z。打印 顺序为12A34B56C……5152Z
- 编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推
- 编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
- 编写一个多线程函数实现对数组排序,要求: 1.至少用两个线程 2.数组的元素值可以事先定义好,或者可以从键盘输入(增加一个线程)。 3.用一个线程对数组排序,用另一个线程输出排序结果。 4.保证先排好序,再输出。
- 编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
- Java:写2个线程,其中一个线程打印1-52,另一个线程打印A-Z,打印顺序应该是12A34B56C...5152Z。
- 写两个线程,一个线程打印1-52,另一个线程打印字母A-Z。打印 顺序为12A34B56C……5152Z
- 3.一个斐波那契数列是由数字1、1、2、3、5、8、13、21、34等等组成的,其中每一个数字(从第三个数字起)都是前两个数字的和。创建一个方法,接受一个整数参数,并显示从第一个元素开始总共由该参数
- 写两个线程,一个线程打印1-52,另一个线程打印字母A-Z顺序为12A34B。。。。。。。。(两个数字一个字母)
- 编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推
- 写两个线程,一个线程打印1-52,另一个线程打印A-Z,打印顺序为12A34B56C......5152Z。
- 编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推
- 笔试题:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。