多线程练习题

1. 创建两个线程,其中一个输出1-52,另外一个输出A-Z。输出格式要求:12A 34B 56C 78D

// 同步方法 synchronized修饰函数
// 思考:如何保证主线程最后的结束而非阻塞?
//注意: notifyall()的位置在当前线程wait()的前面
//java print不换行 println自动换行

// 思考:如何保证主线程最后的结束而非阻塞?
//注意: notifyall()的位置在当前线程wait()的前面
public class examination_16_1 {
    //  这个类相当于共享变量
    //同步监视器类,提供线程安全的方法
    class printResult{
        private int number=1;
        private char character='A';
        //提供两个synchronized方法
        //  synchronized方法  ;notifyall()的位置在当前线程wait()的前面
        public synchronized void printnumber(){
            System.out.print(number+""+(number+1));
            number+=2;
            notifyAll();
                try {
                    //  大于52之后不再等待;
                    if (number <= 52) wait();
                    //使用while(number <= 52) wait();会一直循环,后面notify也跳不出来
                } catch (Exception e) {
                    System.out.println(e.toString());
                }

        }
        public synchronized void printcharacter(){
            System.out.println(character+" ");
            character+=1;
            notifyAll();
            try {
                //  大于Z之后不再等待;如果不加最后不会结束!!阻塞了
                if(character<='Z') wait();
            }catch (Exception e){
                System.out.println(e.toString());
            }
        }
    }
    class Number implements Runnable{
        private printResult printresult;
        public Number(printResult p){
            this.printresult=p;
        }
        private int i=0;
        public void run(){
            for(;i<26;i++) {
                //调用同步监视器中的方法
                printresult.printnumber();
               //System.out.println(Thread.currentThread().getName()+"  "+i);
            }
        }
    }
    class Character implements Runnable{
        private printResult printresult;
        public Character(printResult p){
            this.printresult=p;
        }
        public void run(){
            for(int i=0;i<26;i++) {
                //调用同步监视器中的方法
                printresult.printcharacter();
            }
        }
    }
    public static void main(String[] args){
        examination_16_1 examination=new examination_16_1();
        printResult p = examination.new printResult();
        Number number=examination.new Number(p);
        Character character = examination.new Character(p);
      //  启动两个线程,一个输出数字、一个输出字母
        new Thread(number).start();
        new Thread(character).start();
//        new Thread(number,"线程0").start();
//        new Thread(number,"线程1").start();

        try {
            //希望 子线程在start就绪后立即启动,那么可以将主线程sleep 15毫秒
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

-

2.使用三个线程使得ABC 循环输出十次

// 思考:如何保证主线程最后的结束而非阻塞?

public class examination_16_2 {
    //提供一个包含synchronized 方法的类
    // while(!isA)  用while好,正确,if总是不对
    private boolean isA=true;
    private boolean isB=false;
    private boolean isC=false;
    private int count=0;
    class Print{
        public synchronized void printA(){
            while(isA) {
                System.out.print("A");
                isA=false;
                isB=true;
                isC=false;
                notifyAll();
            }
            while(!isA){
                try{
                     wait();
                }catch (Exception e){
                    System.out.println(e.toString());
                }
            }
        }
        public synchronized void printB() {
            while (isB) {
                System.out.print("B");
                isA = false;
                isB = false;
                isC = true;
                notifyAll();
            }
           while(!isB){
                //  思考::如果没有这句判断,仍然无法将主线程结束??
               //  因为最后输出最后一个C,notify所有线程,这时只有 B、C false会继续阻塞,需要解除
               if(count>=10) break;
                try {
                     wait();
                } catch (Exception e) {
                    System.out.println(e.toString());
                }
            }
        }
        public synchronized void printC() {
            while(isC) {
                System.out.println("C"+" ");
                count++;
                System.out.println("count:"+count);
                isA = true;
                isC = false;
                isB = false;
                notifyAll();
            }
            while(!isC) {
                if(count>=10) break;
                try {
                     wait();
                } catch (Exception e) {
                    System.out.println(e.toString());
                }
            }
        }
        }
    class PrintThreadA implements Runnable{
        private  Print p;
        public PrintThreadA(Print p){
            this.p=p;
        }
        public void run(){
            for(int i=0;i<10;i++)
                p.printA();
        }
    }
    class PrintThreadB implements Runnable{
        private  Print p;
        public PrintThreadB(Print p){
            this.p=p;
        }
        public void run(){
            for(int i=0;i<10;i++) {
                p.printB();
            }
        }
    }
    class PrintThreadC implements Runnable{
        private  Print p;
        public PrintThreadC(Print p){
            this.p=p;
        }
        public void run(){
            for(int i=0;i<10;i++) {
                p.printC();
                //思考::为什么i最后输出不到9 ??
                //因为最后一次输出C后线程被阻塞—— 加上if(count>10) beark; 才会输出
                // i++ 是在循环体内部执行完毕后执行
                System.out.print( "i:" + i + " ");
            }
        }
    }
    public static void main(String[] args){
        examination_16_2 exm =new examination_16_2();
        Print p=exm.new Print();
        PrintThreadA pA = exm.new PrintThreadA(p);
        PrintThreadB pB =exm.new PrintThreadB(p);
        PrintThreadC pC =exm.new PrintThreadC(p);
        new Thread(pA).start();
        new Thread(pB).start();
        new Thread(pC).start();
    }
}

-

3.有三个车库,模拟多个用户停车、离开的效果
//思考1: 生产者消费者模式?
//思考2:还是用一个同步监视器类,提供线程安全的carin、carout函数;;一个入库线程、一个出库线程。

//使用阻塞队列BlockingQueue
public class examination_16_3 {
    class CarStore{
        //阻塞队列
        private BlockingQueue<Integer> bq;
        public CarStore(BlockingQueue<Integer> bq){
               this.bq=bq;
        }
        public synchronized void carin(){
            for(int i=1;i<=3;i++) {
                try {
                    //queue  put方法尝试加入新元素,如果是满队列,会进入wait状态
                    if(!bq.contains(i)) {
                        notifyAll();
                        bq.put(i);
                        Thread.currentThread().sleep(500);
                        System.out.println(Thread.currentThread().getName()+":入库"+i);
                    }
                    //Thread.currentThread().sleep(1000);
                }catch (Exception e){
                    System.out.println(e.toString());
                }
            }
        }
        public synchronized void carout(){
            try {

                Thread.currentThread().sleep(100);
                if(!bq.isEmpty()) System.out.println(Thread.currentThread().getName()+":退出"+bq.peek());
                //queue  take方法尝试取出并删除队首元素,空队列则会进入阻塞状态
                notifyAll();
                bq.take();
            }catch (Exception e){
                System.out.println(e.toString());
            }
        }
    }
    class Carstorein extends Thread {
        private CarStore cs;
        public Carstorein(CarStore cs){  this.cs=cs;}
        public void run() {
            for (int i = 0; i < 100000; i++) {
                cs.carin();
            }
        }
    }
    class Carstoreout extends Thread {
        private CarStore cs;
        public Carstoreout(CarStore cs){  this.cs=cs;}
        public void run() {
            while(true)
                cs.carout();
        }
    }
    public static void main(String[] args){
        examination_16_3 exm =new examination_16_3();
        //共享变量 Blockingqueue
        BlockingQueue<Integer> bq=new ArrayBlockingQueue<Integer>(3);
        CarStore cs =exm.new CarStore(bq);
        exm.new Carstorein(cs).start();
        exm.new Carstorein(cs).start();
        exm.new Carstorein(cs).start();
        exm.new Carstoreout(cs).start();
        exm.new Carstoreout(cs).start();
    }
}

concle result:
Thread-0:入库1
Thread-0:入库2
Thread-0:入库3
Thread-4:退出1
Thread-3:退出2
Thread-2:入库1
Thread-2:入库2
Thread-3:退出3
Thread-3:退出1
Thread-4:退出2
展开阅读全文

没有更多推荐了,返回首页