多线程的训练:
线程共有以下几种状态:新建,运行(可运行),阻塞,等待,及时等待,终止。比如:使用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) + "毫秒");// 查看时间的变化
}
}

1万+

被折叠的 条评论
为什么被折叠?



