【华为机试049】多线程

题目描述:

有4个线程和1个公共的字符数组。线程1的功能就是向数组输出A,线程2的功能就是向字符输出B,线程3的功能就是向数组输出C,线程4的功能就是向数组输出D。要求按顺序向数组赋值ABCDABCDABCD,ABCD的个数由线程函数1的参数指定。

Java实现:

import java.util.Scanner;

//临界资源
class CharBuffer{
    private StringBuffer value = new StringBuffer();//共享变量
    private int num = 0;//添加次数
    private int order = 0;//信号量

    public String getVal() {
        return value.toString();
    }

    public CharBuffer(int num) {
        this.num = num;
    }

    //临界区
    public synchronized void put(char c, int order) {
        if (this.order != order) {
            try {
                this.wait();//将锁让出来
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return;
        }
        value.append(c);//将字母添加到共享资源
        this.order = (this.order + 1) % 4;
        if (this.order == 0)
            num--;
        this.notifyAll();//通知其他处于等待的线程
    }
    public int getNum() {
        return num;
    }

}

class SendThread extends Thread {
    private CharBuffer cb;//共享变量的引用
    private int order = 0;//信号量,约定发送线程的次序
    private char c;

    public SendThread(char c, int order, CharBuffer cb) {
        this.c = c;
        this.order = order;
        this.cb = cb;
    }

    public void run() {
        while (cb.getNum() != 0) {
            cb.put(c, order);//调用临界对象的临界区
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            CharBuffer cb = new CharBuffer(n);
            //创建线程
            SendThread st1 = new SendThread('A', 0, cb);
            st1.start();
            SendThread st2 = new SendThread('B', 1, cb);
            st2.start();
            SendThread st3 = new SendThread('C', 2, cb);
            st3.start();
            SendThread st4 = new SendThread('D', 3, cb);
            st4.start();
            try {
                st1.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(cb.getVal());
        }
    }
}

关键点:

  • 这个题目的意思是在多线程随机抢占CPU的前提下,对临界区域的操作要满足一定的顺序
  • 开启四个线程后每个线程都在试图把自己的字符以自己的顺序放入临界区域
  • synchronized可以保证代码块具有可见性及原子性
  • synchronized的可见性保证当前线程解锁前对共享变量的修改在下次加锁前对其他线程可见
  • void join() 若线程A调用线程B的join方法,那么线程A的运行会被暂停,直到线程B运行结束

你可能感兴趣的:(华为机试题集Java实现)