多线程实现的一些问题

龟兔赛跑

童话故事里面龟兔赛跑比赛中,兔子比赛途中休息三次,而乌龟一直努力坚持奔跑从而赢得了比赛,那么在多线程中怎样完成这样的问题呢

代码:

创建了一个兔子线程

package com.company.test01;

import static java.lang.Thread.sleep;

public class RabbitThread implements Runnable{
    @Override
    public void run() {
        try {
            for (int i=1;i<=100;i++){
                if(i==25) {
                    System.out.println("兔子跑了 "+i+"米");
                    System.out.println("兔子累了要休息一会儿ZZZZZZ");
                    sleep(2);//兔子第一次休息
                }
                System.out.println("兔子在奔跑 ==="+i);
                if(i==55) {
                    System.out.println("兔子跑了 "+i+"米");
                    System.out.println("兔子累了要休息一会儿ZZZZZZ");
                    sleep(2);//兔子第二次休息
                }
                if(i==75) {
                    System.out.println("兔子跑了 "+i+"米");
                    System.out.println("兔子累了要休息一会儿ZZZZZZ");
                    sleep(2);//兔子第三次休息
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

创建了一个乌龟线程

package com.company.test01;

public class TortoiseThread implements  Runnable{
    @Override
    public void run() {
        for (int i=1;i<=100;i++){
            if(i==5){
                System.out.println("乌龟跑了====="+i+"米");
            }
            if(i==45){
                System.out.println("乌龟跑了====="+i+"米");
            }
            if(i==75){
                System.out.println("乌龟跑了====="+i+"米");
            }
            System.out.println("乌龟在努力跑 "+i);
        }
    }
}

比赛开始:

package com.company.test01;

public class MuItiThread {
    public static void main(String[] args) {
        System.out.println("+++++++=龟兔比赛开始了++++++");
        Thread t1=new Thread(new RabbitThread());
        t1.setPriority(10);//代表兔子的速度快
        t1.start();
        Thread t2=new Thread(new TortoiseThread());
        t2.setPriority(7);//乌龟的速度慢
        t2.start();
    }
}

这里面的关键在于给线程优先级的创建,以及线程的休眠,线程优先级的创建代表乌龟和兔子的速度,而线程的休眠代表兔子的休息。

编写一个有两个线程的程序,第一个线程用来计算2~100000之间的素数的个数,第二个线程用来计算100000~200000之间的素数的个数,最后输出结果。

代码:

package com.company.test02;

public class PriNumCalculation extends Thread{
    //成员变量
    int a;
    int b;
    int c=0;//代表素数的个数
    //创建有参的构造函数
    public PriNumCalculation(int a,int b){
        this.a=a;
        this.b=b;
    }

    public void run() {//run方法
        int e=0;
        int f=0;
        for(int m=a;m<=b;m++) {//在指定范围内进行循环判断
            for(int h=1;h<=m;h++) {//从1到它本身判断能整除的有几个
                f=m%h;
                if(f==0){//能被整除e进行++
                    e++;
                }
            }
            if(e==2) {//当e等于2的时候表示得到一个素数
                c=c+1;
            }
            e=0;//当超过2时此数不为素数,e赋值为0
        }
        System.out.println("输出"+a+"到"+b+"之间的质数个数:"+c);
    }

    public static void main(String[] args) {
        PriNumCalculation t1=new PriNumCalculation(2,10000);
        t1.start();
        PriNumCalculation t2=new PriNumCalculation(10000,20000);
        t2.start();
    }
}

使用多线程实现多个文件同步复制功能,并在控制台显示复制的进度,进度以百分比表示。例如:把文件A复制到E盘某文件夹下,在控制台上显示“XXX文件已复制10%”,“XXX文件已复制20%”……“XXX文件已复制100%”,“XXX复制完成!”

代码:

package com.company.test03;

import java.io.*;
import java.text.DecimalFormat;

public class FileReplication  extends Thread{
    public File older;// 源文件路径
    public File newer;// 复制目标路径

    public FileReplication(String older, String newer) {//有参构造函数
        this.older = new File(older);
        this.newer = new File(newer);
    }

    @Override
    public void run() {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(older);
            fos = new FileOutputStream(newer);
            byte[] b = new byte[1024];// 声明一个字节数组,每次读取的数据存到该字节数组里
            int length = 0;// 返回每次读取的数据长度
            long len = older.length();// 获取源文件的长度
            double temp = 0;
            DecimalFormat df = new DecimalFormat("##%");
            while ((length = fis.read(b)) != -1) {
                fos.write(b, 0, length);// 把每次读取的内容,输出到目标路径文件中
                temp += length;// 把每次读取的数据长度累加
                double d = temp / len;// 计算出已经读取的长度占文件总长度的比率
                int jd = (int) d;
                if (jd % 10 == 0) {
                    System.out.println(older.getName() + "文件复制了:" + df.format(d));
                }
            }
            System.out.println(older.getName() + "复制完毕!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();//无论出不出异常最后都要关闭IO流
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) {
        FileReplication fileReplication1=new FileReplication("C:\\test\\t1.txt","D:\\test\\t1.txt");
        fileReplication1.start();
        FileReplication fileReplication2=new FileReplication("C:\\test\\t2.txt","D:\\test\\t2.txt");
        fileReplication2.start();
        FileReplication fileReplication3=new FileReplication("C:\\test\\t3.txt","D:\\test\\t3.txt");
        fileReplication3.start();
    }

}

设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。考虑到线程的安全性写出程序。

代码

package com.company.test04;

public class ThreadAddSub {
    private int j = 1;//成员变量

    private synchronized void add(){//对j进行++设置同步
        j++;
        System.out.println(Thread.currentThread().getName()+"add:"+j);
    }

    private synchronized void sub(){//对j进行--设置同步
        j--;
        System.out.println(Thread.currentThread().getName()+"sbu:"+j);
    }

    private class Add implements Runnable{//增加的线程类
        public void run() {
            try {
                for (int i = 0; i < 100; i++) {
                    if(j>100){
                        wait(3);//防止超过100
                    }
                    add();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private class Sub implements Runnable{//减少的线程类
        public void run() {
            try {
                for (int i = 0; i < 100; i++) {
                    if(j<0){
                        wait(3);//防止减少为负数
                    }
                    sub();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        ThreadAddSub tt = new ThreadAddSub();
        Add add = tt.new Add();
        Sub sub = tt.new Sub();
        Thread t1=new Thread(add);
        t1.start();
        Thread t2=new Thread(sub);
        t2.start();
        Thread t3=new Thread(add);
        t3.start();
        Thread t4=new Thread(sub);
        t4.start();
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值