首页 > 编程语言 > 详细

【自学java笔记#第三十三天#】线程练习题

时间:2020-04-15 17:55:08      阅读:79      评论:0      收藏:0      [点我收藏+]

一、写两个线程,一个线程打印 1-52,另一个线程打印A-Z,打印顺序是12A34B…5152Z。

1、开始审题没审清楚,所以写了一个三个线程版的程序:

测试类:

public class Test 
{
    public static void main(String[] args) {
        PrintNumChar p=new PrintNumChar();
        MyRunnable my=new MyRunnable(p);
        Thread t1=new Thread(my,"A");
        Thread t2=new Thread(my,"B");
        Thread t3=new Thread(my,"C");
        t1.start();
        t2.start();
        t3.start();
        }
}

打印类:

public class PrintNumChar 
{
    //定义一个成员变量,判断输出的内容(是1-26或是27-52或是A-Z)
    private int flag=1;
    
    //定义一个成员变量,用作计数器
    private int count=0;
    
    //定义三个成员变量,作为3种内容的输出初始值
    private int num1=1;
    private int num2=2;
    private char ch=‘A‘;
    
    //定义一个成员方法,获得计数器的值
    public int getCount() {
        return count;
    }
    
    //输出1-26
    public synchronized void printNum1() {
        while(flag!=1) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(num1);
        flag=2;
        count++;
        num1+=2;
        notifyAll();
    }
    
    //输出27-52
    public synchronized void printNum2() {
        while(flag!=2) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(num2);
        flag=3;
        count++;
        num2+=2;
        notifyAll();
    }
    
    //输出A-Z
    public synchronized void printChar() {
        while(flag!=3) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(ch);
        flag=1;
        count++;
        ch+=1;
        notifyAll();
    }        
}

//用实现Runnable接口的方式来实现多线程
class MyRunnable implements Runnable{
    private PrintNumChar p;
    
    public MyRunnable(PrintNumChar p) {
        this.p=p;
    }
    
    public void run() {
        while(p.getCount()<76) {
            if(Thread.currentThread().getName().equals("A")) {
                p.printNum1();
            }
            else if(Thread.currentThread().getName().equals("B")) {
                p.printNum2();
            }
            else if(Thread.currentThread().getName().equals("C")) {
                p.printChar();
            }
        }
    }
}

2、仔细审题之后,再改进为两个线程版的程序:

测试类:

package print1;

public class Test 
{
    public static void main(String[] args) {
        PrintNumChar p=new PrintNumChar();
        MyRunnable my=new MyRunnable(p);
        Thread t1=new Thread(my,"A");
        Thread t2=new Thread(my,"B");
        t1.start();
        t2.start();
        }
}

打印类:

package print1;
/**
 * 写两个线程,一个线程打印 1-52,另一个线程打印A-Z,打印顺序是12A34B…5152Z。
 */

public class PrintNumChar 
{
    //定义一个成员变量,判断输出的内容(是1-52或是A-Z)
    private int flag=1;
    
    //定义一个成员变量,用作计数器
    private int count=0;
    
    //定义三个成员变量,作为3种内容的输出初始值
    private int num1=1;
    private char ch=‘A‘;
    
    //定义一个成员方法,获得计数器的值
    public int getCount() {
        return count;
    }
    
    //输出1-52
    public synchronized void printNum1() {
        while(flag!=1) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(num1*2-1);
        System.out.print(num1*2);
        flag=2;
        count++;
        num1++;
        notifyAll();
    }
    
    //输出A-Z
    public synchronized void printChar() {
        while(flag!=2) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(ch);
        flag=1;
        count++;
        ch+=1;
        notifyAll();
    }        
}

//用实现Runnable接口的方式来实现多线程
class MyRunnable implements Runnable{
    private PrintNumChar p;
    
    public MyRunnable(PrintNumChar p) {
        this.p=p;
    }
    
    public void run() {
        while(p.getCount()<51) {
            if(Thread.currentThread().getName().equals("A")) {
                p.printNum1();
            }
            else if(Thread.currentThread().getName().equals("B")) {
                p.printChar();
            }
        }
    }
}

二、编写一个程序,启动三个线程,三个线程的名称分别是 A,B,C。

 每个线程将自己的名称在屏幕上打印5遍,打印顺序是ABCABC…

分析:结题思路和上面的题一致,只是输出的内容不一样而已。

测试类:

class Test{
    public static void main(String[] args) {
        Print print=new Print();
        MyThread my=new MyThread(print);
        Thread t1=new Thread(my,"A");
        Thread t2=new Thread(my,"B");
        Thread t3=new Thread(my,"C");
        t1.start();
        t2.start();
        t3.start();
        
    }
}

打印类:

public class Print 
{
    //打印哪个字符的标志
    private int flag=1;
    
    //打印次数计数器
    private int count=0;
    
    //获得打印次数
    public int getCount() {
        return count;
    }
    
    //打印"A"的方法
    public synchronized void printA() {
        while(flag!=1) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(Thread.currentThread().getName());
        
        //打印完成后,将标识改为2,计数器也加1,并唤醒其他等待线程
        flag=2;
        count++;
        notifyAll();
    }
    
    public synchronized void printB() {
        while(flag!=2) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(Thread.currentThread().getName());
        flag=3;
        count++;
        notifyAll();
    }
    
    public synchronized void printC() {
        while(flag!=3) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print(Thread.currentThread().getName());
        flag=1;
        count++;
        notifyAll();
    }

}

//通过实现Runnable接口的方式来实现多线程
class MyThread implements Runnable{
    private Print print;
    public MyThread(Print print) {
        this.print=print;
    }
    public void run() {
        while(print.getCount()<13) {
            if(Thread.currentThread().getName().equals("A")) {
                print.printA();
            }
            else if(Thread.currentThread().getName().equals("B")) {
                print.printB();
            }
            else if(Thread.currentThread().getName().equals("C")) {
                print.printC();
            }
        }
    }
}

三、编写程序实现,子线程循环3次,接着主线程循环5次,接着再子线程循环3次,主线程循环5次,如此反复,循环3次。

测试类:

public class Test {
    public static void main(String[] args) {
        ThreadFunction f2=new ThreadFunction();
        
        //子线程循环3次:用start()方法调用3次run()方法
        new Thread(new Runnable() {
            public void run() {
                for(int i=0;i<3;i++) {
                    f2.subFunction();
                }
            }
        }).start();
        
        //主线程循环3次:普通的方法调用3次
        for(int i=0;i<3;i++) {
            f2.mainFunction();
        }
    }
}

打印类:

class ThreadFunction{
    private boolean flag=false;
    
    public synchronized void mainFunction() {
        while(!flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        //主线程输出5次
        for(int i=0;i<5;i++) {
            System.out.println("mainFunction"+i);
        }
        notify();
        flag=false;
    }
    
    public synchronized void subFunction() {
        while(flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        //子线程输出3次
        for(int i=0;i<3;i++) {
            System.out.println("subFunction"+i);
        }
        notify();
        flag=true;
    }
    
    
}

四、总结

今天做的所有线程练习,基本上都是采用的synchronized关键字的做法。在学线程的最初级阶段,我感觉把这一种做法学透彻就够用了。拿第三题来说,不仅用了线程同步的知识,还涉及到了前面学过的匿名内部类。但是要想彻底掌握线程的相关知识点,做这点打印程序的练习还是不够的。所以后续会多做几道生产者消费者的题来巩固一下。

【自学java笔记#第三十三天#】线程练习题

原文:https://www.cnblogs.com/yizhinailu/p/12706583.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!