多线程练习实例

多线程的训练:
线程共有以下几种状态:新建,运行(可运行),阻塞,等待,及时等待,终止。比如:使用new操作符创建新线程时,线程处于新建状态,当调用start()方法时,线程处于运行(可运行)状态。
第一题:编写类ThreadState,该类实现了Runnable接口。该类定义了三个方法:
waitForASecond():使当前线程等待0.5秒
waitForYears():使当前线程永久等待,直到其他线程调用notify()或notifyAll()方法
notifyNow():唤醒由调用wait()方法进入等待状态的线程
在run()方法中,调用了waitForASecond()和waitForYears()方法
编写类Test进行测试,在main()方法中,输出了线程的各种不同状态:
新建线程:NEW
启动线程:RUNNABLE
计时等待:TIMED_WAITING
等待线程:WAITING
唤醒线程:BLOCKED
终止线程:TERMINATED

第二题 线程插队的训练:
1 编写类EmergencyThread,该类实现了Runnable接口。在run()方法中,每隔0.1秒输出 一条语句。
2 编写类JionThread用来测试,在该类中使用EmergencyThread创建并运行新的线程,使用join()方法让新线程优先于当前线程运行。
如果插队,运行结果如下:
正常情况:1号车出发!
紧急情况:1号车出发!
正常情况:2号车出发!
紧急情况:2号车出发!
正常情况:3号车出发!
紧急情况:3号车出发!
正常情况:4号车出发!
紧急情况:4号车出发!
正常情况:5号车出发!
紧急情况:5号车出发!
如果插队,运行结果如下:
正常情况:1号车出发!
紧急情况:1号车出发!
紧急情况:2号车出发!
紧急情况:3号车出发!
紧急情况:4号车出发!
紧急情况:5号车出发!
正常情况:2号车出发!
正常情况:3号车出发!
正常情况:4号车出发!
正常情况:5号车出发!
第三题:传统多线程程序的创建与线程池管理多线程的对比
给定一个测试用的Runnable接口实现类,代码如下:

public class TempThread implements Runnable {// 测试用的Runnable接口实现类
private int id = 0;

@Override
public void run() {// run()方法给id做自增运算
    id++;
}

}
请编写一个测试程序,用两种方式实现一千个线程的创建,第一种方式是Thread类来实现多线程,第二种用线程池来实现多线程。分别计算这两种模式所用的系统内存和时间。
以下两句代码可以获取系统的可用内存:
Runtime run = Runtime.getRuntime();
run.freeMemory();
运行结果如下(不同的计算机数据可能不同):
独立运行1000个线程所占用的内存:7991352字节
独立创建1000个线程所消耗的时间:491毫秒
使用连接池运行1000个线程所占用的内存:1998704字节
使用连接池创建1000个线程所消耗的时间:3毫秒

第一题参考答案:

public class ThreadState implements Runnable {
    public synchronized void waitForASecond() throws InterruptedException {
        wait(500); // 使当前线程等待0.5秒或其他线程调用notify()或notifyAll()方法
    }
    
    public synchronized void waitForYears() throws InterruptedException {
        wait(); // 使当前线程永久等待,直到其他线程调用notify()或notifyAll()方法
    }
    
    public synchronized void notifyNow() throws InterruptedException {
        notify(); // 唤醒由调用wait()方法进入等待状态的线程
    }
    
    public void run() {
        try {
            waitForASecond(); // 在新线程中运行waitForASecond()方法
            waitForYears(); // 在新线程中运行waitForYears()方法
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        ThreadState state = new ThreadState();// 创建State对象
        Thread thread = new Thread(state);// 利用State对象创建Thread对象
        System.out.println("新建线程:" + thread.getState());// 输出线程状态
        thread.start(); // 调用thread对象的start()方法,启动新线程
        System.out.println("启动线程:" + thread.getState());// 输出线程状态
        Thread.sleep(100); // 当前线程休眠0.1秒,使新线程运行waitForASecond()方法
        System.out.println("计时等待:" + thread.getState());// 输出线程状态
        Thread.sleep(1000); // 当前线程休眠1秒,使新线程运行waitForYears()方法
        System.out.println("等待线程:" + thread.getState());// 输出线程状态
        state.notifyNow(); // 调用state的notifyNow()方法
        System.out.println("唤醒线程:" + thread.getState());// 输出线程状态
        Thread.sleep(1000); // 当前线程休眠1秒,使新线程结束
        System.out.println("终止线程:" + thread.getState());// 输出线程状态
    }
    
}

第二题 参考答案:

public class EmergencyThread implements Runnable {
    
    @Override
    public void run() {
        for (int i = 1; i < 6; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("紧急情况:" + i + "号车出发!");
        }
    }
}
public class JoinThread {
    
    public static void main(String[] args) {
        Thread thread = new Thread(new EmergencyThread());
        thread.start();
        for (int i = 1; i < 6; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("正常情况:" + i + "号车出发!");
            try {
             thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

第三题参考答案:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolTest {
    public static void main(String[] args) {
        Runtime run = Runtime.getRuntime();// 创建Runtime对象
        run.gc();// 运行垃圾回收器,这样可以减少误差
        long freeMemory = run.freeMemory();// 获得当前虚拟机的空闲内存
        long currentTime = System.currentTimeMillis();// 获得当前虚拟机的时间
        for (int i = 0; i < 10000; i++) {// 独立运行1000个线程
            new Thread(new TempThread()).start();
        }
        System.out.println("独立运行1000个线程所占用的内存:" + (freeMemory - run.freeMemory()) + "字节");// 查看内存的变化
        System.out.println("独立创建1000个线程所消耗的时间:" + (System.currentTimeMillis() - currentTime) + "毫秒");// 查看时间的变化
        
        run.gc();// 运行垃圾回收器
        freeMemory = run.freeMemory();// 获得当前虚拟机的空闲内存
        currentTime = System.currentTimeMillis();// 获得当前虚拟机的时间
        ExecutorService executorService = Executors.newFixedThreadPool(2);// 创建线程池
        for (int i = 0; i < 1000; i++) {// 使用线程池运行1000个线程
            executorService.submit(new TempThread());
        }
        System.out.println("使用连接池运行1000个线程所占用的内存:" + (freeMemory - run.freeMemory()) + "字节");// 查看内存的变化
        System.out.println("使用连接池创建1000个线程所消耗的时间:" + (System.currentTimeMillis() - currentTime) + "毫秒");// 查看时间的变化
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JD_George

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值