NumberThread 类是负责循环输出数字 1-26 的线程一
UpperCharThread 类是负责循环输出大写字母 A-Z 的线程二
LowerCharThread 类是负责循环输出小写字母 a-z 的线程三现在要实现的是一次输出 数字、大写字母、小写如:
1 A a
2 B b
. . .
. . .
26 Z z使用synchronized 和 wait() notify() 完成

解决方案 »

  1.   


    package hr.test;
    //临界区,用于控制打印线程的工作顺序和互斥操作
    class Mutex{
    private int order=1; //记录线程顺序号
    private int maxNum=0; //最大线程数

    Mutex(int num){
    this.maxNum=num;
    }
    //循环设置下一次要打印的顺序号
    public void setOrder(){
    this.order=(++order)<=maxNum?order:1;
    }
    //得到顺序号
    public int getOrder(){
    return this.order;
    }
    }
    //打印工作
    class PrintRunnable implements Runnable{

    private Object[] cont=null; //打印内容
    private int order=-1; //当前线程的打印顺序
    private Mutex mutex=null; //临界区对象

    PrintRunnable(Object[] c,int o,Mutex m){
    this.cont=c;
    this.order=o;
    this.mutex=m;
    }

    public void run(){
    try{
    //循环打印内容
    for(Object c:cont){
    //互斥操作临界区
    synchronized(mutex){
    //如果当前工作线程的顺序号不等于临界区的顺序号,则工作线程等待阻塞,并放弃锁
    while(mutex.getOrder()!=this.order)
    mutex.wait();
    //打印内容
    System.out.println(c); 
    //设置下一次允许打印的线程顺序
    mutex.setOrder();
    //唤醒在临界区等待的所有线程
    mutex.notifyAll();
    }
    }
    }catch(InterruptedException e){
    e.printStackTrace();
    }

    }
    }//测试
    public class Test { public static void main(String[] args){
    Integer[] number={1,2,3,4};
    Character[] upperChar={'A','B','C','D'};
    Character[] lowerChar={'a','b','c','d'};
    Mutex mutex=new Mutex(3);
    new Thread(new PrintRunnable(number,1,mutex)).start();
    new Thread(new PrintRunnable(upperChar,2,mutex)).start();
    new Thread(new PrintRunnable(lowerChar,3,mutex)).start();
    }
    }
      

  2.   


    谢谢解答!
    我还想再问下,如果用以下的代码作为基础该怎么实现,这个是作业...
    package com.test;class NumberThread extends Thread { public void run() {
    for (int i = 1; i <= 26; i++) {
    System.out.println(i);
    }
    }
    }class BigCharThread extends Thread {
    public void run() {
    for (int i = 'A'; i <= 'Z'; i++) {
    System.out.println((char) i);
    }
    }
    }class SmallCharThread extends Thread {
    public void run() {
    for (int i = 'a'; i <= 'z'; i++) {
    System.out.println((char) i);
    }
    }
    }public class ThreeThread {
    public static void main(String[] args) {
    NumberThread num = new NumberThread();
    BigCharThread big = new BigCharThread();
    SmallCharThread small = new SmallCharThread();
    num.start();
    big.start();
    small.start();
    }
    }
      

  3.   

    把上面大虾的东东小改进一下 呵呵
    class Mutex{
        private int order=1; //记录线程顺序号
        private int maxNum=0; //最大线程数
        
        Mutex(int num){
            this.maxNum=num;
        }
        //循环设置下一次要打印的顺序号
        public void setOrder(){
            this.order=(++order)<=maxNum?order:1;
        }
        //得到顺序号
        public int getOrder(){
            return this.order;
        }
    }
    //打印工作
    class PrintRunnable implements Runnable{
        
        private Object[] cont=null; //打印内容
        private int order=-1; //当前线程的打印顺序
        private Mutex mutex=null; //临界区对象
        
        PrintRunnable(Object[] c,int o,Mutex m){
            this.cont=c;
            this.order=o;
            this.mutex=m;
        }
        
        public void run(){
            try{
                //循环打印内容
                for(Object c:cont){
                    //互斥操作临界区
                    synchronized(mutex){
                        //如果当前工作线程的顺序号不等于临界区的顺序号,则工作线程等待阻塞,并放弃锁
                        while(mutex.getOrder()!=this.order)
                            mutex.wait();
                        //打印内容
                        System.out.print(c+" "); 
                        if(mutex.getOrder()==3)
                         System.out.println();
                        //设置下一次允许打印的线程顺序
                        mutex.setOrder();
                        //唤醒在临界区等待的所有线程
                        mutex.notifyAll();
                    }
                }
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            
        }
    }//测试
    public class ThreeThread {    public static void main(String[] args){
            Integer[] number={1,2,3,4};
            Character[] upperChar={'A','B','C','D'};
            Character[] lowerChar={'a','b','c','d'};
            Mutex mutex=new Mutex(3);
            new Thread(new PrintRunnable(number,1,mutex)).start();
            new Thread(new PrintRunnable(upperChar,2,mutex)).start();
            new Thread(new PrintRunnable(lowerChar,3,mutex)).start();
        }
    }输出结果:
    1 A a 
    2 B b 
    3 C c 
    4 D d 
      

  4.   

    输出的话使用三个线程输出控制不太好控制,不如2楼那种方式方便
    我线程方面也不太会,但是给写了一个程序,供大家讨论:package thread;class NumberThread extends Thread {
    int index = 0;
    Munex mu = new Munex(); public NumberThread(Munex mu) {
    this.mu = mu;
    } public void run() {
    for (int i = 1; i <= 26; i++) {
    mu.shuChu(index);
    System.out.print(i + " ");
    }
    } public int getIndex() {
    return index;
    }
    }class BigCharThread extends Thread {
    int index = 1;
    Munex mu = new Munex(); public BigCharThread(Munex mu) {
    this.mu = mu;
    } public void run() {
    for (int i = 'A'; i <= 'Z'; i++) {
    mu.shuChu(index);
    System.out.print((char) i + " ");
    }
    } public int getIndex() {
    return index;
    }
    }class SmallCharThread extends Thread {
    int index = 2;
    Munex mu = new Munex(); public SmallCharThread(Munex mu) {
    this.mu = mu;
    } public void run() {
    for (int i = 'a'; i <= 'z'; i++) {
    mu.shuChu(index);
    System.out.println((char) i + " ");
    }
    }
    }class Munex {
    int index = 0; synchronized public void shuChu(int index) {
    while (this.index != index) {
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    // System.out.println(index+"@@@");
    setIndex();
    //问题是为什么在这里休眠一会结果就没有问题,不休眠就会有问题呢?
    //希望高手能给予指点一下。
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    this.notifyAll();
    } public void setIndex() {
    if (index == 2)
    index = 0;
    else
    index++;
    }
    }public class ThreeThread {
    public static void main(String[] args) {
    Munex mu = new Munex();
    NumberThread num = new NumberThread(mu);
    BigCharThread big = new BigCharThread(mu);
    SmallCharThread small = new SmallCharThread(mu);
    num.start();
    big.start();
    small.start();
    }
    }
    输出结果:
    1 A a 
    2 B b 
    3 C c 
    4 D d 
    5 E e 
    6 F f 
    7 G g 
    8 H h 
    9 I i 
    10 J j 
    11 K k 
    12 L l 
    13 M m 
    14 N n 
    15 O o 
    16 P p 
    17 Q q 
    18 R r 
    19 S s 
    20 T t 
    21 U u 
    22 V v 
    23 W w 
    24 X x 
    25 Y y 
    26 Z z 
    在这里我有个问题就是:
    为什么在Munex类里休眠一会结果就没有问题,不休眠就会有问题呢?
    希望高手能给予指点一下。
      

  5.   


    package com.test;class NumberThread extends Thread {    public void run() {
            for (int i = 1; i <= 26; i++) {
                System.out.println(i);
            }
        }
    }class BigCharThread extends Thread {
        public void run() {
            for (int i = 'A'; i <= 'Z'; i++) {
                System.out.println((char) i);
            }
        }
    }class SmallCharThread extends Thread {
        public void run() {
            for (int i = 'a'; i <= 'z'; i++) {
                System.out.println((char) i);
            }
        }
    }public class ThreeThread {
        public static void main(String[] args) {
            NumberThread num = new NumberThread();
            BigCharThread big = new BigCharThread();
            SmallCharThread small = new SmallCharThread();
            num.start();
            big.start();
            small.start();
        }
    }使用join()方法,在大写字母里  写数字线程.join()  在小写字母里  写 大写字母.join()
      

  6.   


    实现代码如下:
    package com.test;class NumThread1 extends Thread {

    public void run() {
    for(int i=1;i<=26;i++){
    System.out.println(i);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }class BigCharThread extends Thread{
    private Thread person;
    public BigCharThread(Thread person) {
    this.person=person;
    }
    public void run() {
    try {
    person.join();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
        for(int i='A';i<='Z';i++){
    System.out.println((char)i);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }class SmallCharThread extends Thread{
    private Thread person;
    public SmallCharThread(Thread person) {
    this.person=person;
    }
    public void run() {
    try {
    person.join();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
                for(int i='a';i<='z';i++){
    System.out.println((char)i);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }
    public class NumChar {
    public static void main(String[] args) {
    NumThread1 n=new NumThread1();
    BigCharThread b=new BigCharThread(n);
    SmallCharThread s=new SmallCharThread(b);
    n.start();
    s.start();
    b.start();


    }}
      

  7.   

    2楼的代码还比较靠谱。但有个问题,全局只有一个互斥锁,每次notifyAll后所有线程都被激活,却只有一个线程继续工作,其他线程则重复等待。这道题只是3个线程,如果线程多了,这种虚假唤醒会影响性能。
    下面的代码使用了一个令牌传递的机制,每个拥有控制权的线程在做完自己的事情后把控制权交给下一个线程,而不是唤醒所有线程class ThreadNode
    {
        boolean hasToken = false;//true if this is first Thread
        Node next;//need initialized
        synchronized void waitToken() throws InterruptedException
        {
            while(!hasToken)
                this.wait();
        }
        void switchNext()
        {
            this.hasToken = false;
            next.setToken();
        }
        synchronized void setToken()
        {
            this.hasToken = true;
            this.notifyAll();
        }
        public void loop() throws InterruptedException
        {
            for(;;)
            {
                this.waitToken();
                //do my jobs
                this.switchNext();
            }
        }
    }