您的位置:首页 > 其它

创建两个线程,其中一个输出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();
}
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐