用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

柯侧耳倾听者    -  云代码空间

—— 翱翔在Java世界的海洋之上

Java多线程编程

2017-12-14|911阅||

摘要:一、实验目的 1、理解线程的基本概念,掌握Java创建线程的方式。 2、掌握进程间参数传递方式以及线程同步、线程间通信的方法。 3、掌握线程池的工作原理和使用。


一、实验目的

1、理解线程的基本概念,掌握Java创建线程的方式。

2、掌握进程间参数传递方式以及线程同步、线程间通信的方法。

3、掌握线程池的工作原理和使用。

 

二、预习内容及要求(要求写出预习内容)

1、掌握不同类型的输入输出流类,标准数据流、文件流、数据输入输出流、对象流等。

2、编程时,应考虑异常处理。

 

三、实验内容、操作过程及实验结果记录

实验题1 阅读运行下列程序,分析其运行结果。

应用背景:分别使用单线程、多线程、线程池技术计算1000000~5000000之间的素数,并统计线程花费的计算时间,同时比较三种方式的速度快慢。

注意:在单线程模式中,使用循环分别判断每个数是否是质数;在多线程和线程池中,需要将计算任务分配给各个线程。

主要源代码见CalPrimeSingleThread.java、CalPrimeMultiThread.java以及CalPrimeThreadPool.java三个文档。

1、使用单线程计算素数。CalPrimeSingleThread.java代码如下:

Package day01;

import java.io.BufferedOutputStream;

import java.io.DataOutputStream;

import java.io.FileOutputStream;

public class CalPrimeSingleThread {

long primeCount = 0;

public void calPrime(long start, long end) throws Exception {

for (long i = start; i <end; ++i) {

if (isPrime(i)) {

primeCount++;

}

}

}

public boolean isPrime(long n) {

for (long i = 2; i <= Math.sqrt(n); ++i)

if (n % i == 0)

return false;

return true;

}

public static void main(String[] args) throws Exception {

long start = 1000000;

long end = 5000000;

CalPrimeSingleThread prime = new CalPrimeSingleThread();

long startTime = System.nanoTime();

prime.calPrime(start, end);

double estimatedTime = (System.nanoTime() - startTime) / 1000000000.0;

 System.out.printf("使用单线程计算%d~%d之间的质数\n",start, end);

System.out.println("共有质数" + prime.primeCount + "个,花费时间为"

+ estimatedTime + "秒.");

}

}

 

 

 

2、使用多线程计算素数。CalPrimeMultiThread.java代码如下:

Package day01;

import java.io.BufferedOutputStream;

import java.io.DataOutputStream;

import java.io.FileOutputStream;

import java.util.Vector;

import java.util.concurrent.CopyOnWriteArrayList;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.atomic.AtomicInteger;

public class CalPrimeMultiThread {

public static CountDownLatch counter;

public static AtomicInteger numOfPrime;

public static void main(String[] args) throws InterruptedException {

long start = 1000000;

long end = 5000000;

int totalThreads = 10;

CalPrimeMultiThread calPrime = new CalPrimeMultiThread();

calPrime.counter = new CountDownLatch(totalThreads);

calPrime.numOfPrime = new AtomicInteger(0);

long startTime = System.nanoTime();

long len = (end - start) / totalThreads;

for (long i = 0; i < totalThreads; i++) {

Thread t = new Thread(new PrimeThread(start + i * len, start

+ (i + 1) * len-1, calPrime));

t.start();

}

calPrime.counter.await();

double estimatedTime = (System.nanoTime() - startTime) / 1000000000.0;

System.out.printf("使用多线程计算%d~%d之间的质数\n",start, end);

System.out.printf("共有质数%d个,花费时间为%.2f秒.\n",

calPrime.numOfPrime.get(),

estimatedTime);

}

}

class PrimeThread implements Runnable {

long startPos;

long endPos;

CalPrimeMultiThread result;

public PrimeThread(long start, long end, CalPrimeMultiThread result) {

this.startPos = start;

this.endPos = end;

this.result = result;

}

public boolean isPrime(long n) {

for (long i = 2; i <= Math.sqrt(n); ++i)

if (n % i == 0)

return false;

return true;

}

public void run() {

for (long i = startPos; i <=endPos; ++i) {

if (isPrime(i))

result.numOfPrime.incrementAndGet();

}

result.counter.countDown();

}

}

 

 

 

3、使用线程池计算素数。CalPrimeThreadPool.java代码如下:

    Package day01;

import java.io.BufferedOutputStream;

import java.io.DataOutputStream;

import java.io.FileOutputStream;

import java.util.Vector;

import java.util.concurrent.CopyOnWriteArrayList;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.atomic.AtomicInteger;

public class CalPrimeThreadPool {

// AtomicInteger提供原子方式更新int的值

public static AtomicInteger numOfPrime;

public static void main(String[] args) throws InterruptedException {

long start = 1000000;

long end = 5000000;

ExecutorService pool = Executors.newFixedThreadPool(20);

CalPrimeThreadPool calPrime = new CalPrimeThreadPool();

calPrime.numOfPrime = new AtomicInteger(0);

long startTime = System.nanoTime();

int range = 100000;

for (long i = 0; i < (end - start) / range; i++) {

pool.submit(new WorkThread(start + i * range, start + (i + 1)

* range, calPrime));

}

pool.shutdown();

pool.awaitTermination(10, TimeUnit.DAYS);

double estimatedTime = (System.nanoTime() - startTime) / 1000000000.0;

System.out.printf("使用线程池计算%d~%d之间的质数\n", start, end);

System.out.printf("共有质数%d个,花费时间为%.2f秒.\n", calPrime.numOfPrime.get(),

estimatedTime);

}

}

class WorkThread implements Runnable {

long startPos;

long endPos;

CalPrimeThreadPool result;

public WorkThread(long startPos, Long endPos, CalPrimeThreadPool result) {

this.startPos = startPos;

this.endPos = endPos;

this.result = result;

}

public boolean isPrime(long n) {

for (long i = 2; i <= Math.sqrt(n); ++i)

if (n % i == 0)

return false;

return true;

}

public void run() {

for (long i = startPos; i < endPos; ++i) {

if (isPrime(i))

result.numOfPrime.incrementAndGet();

}

}

}

 

 

四、实验过程中所遇问题思考与讨论(可写个人体会,或相关理论知识,根据个人具体情况选做)

     通过这次的学习与实验,我初步掌握了网络编程中的一些用法和问题,也更加了解了网络编程中的一些基本概念,为今后更好的学习网络编程做好铺垫,在学习的过程中,我更加深刻的体会到与老师和同学间的交流与合作是多么的重要,所以在今后的学习与实验当中,要善于发现问题,更要及时与老师反馈问题所在,并与老师和同学交流学习经验,共同解决问题,这样才能更好的学好网络编程。

    

顶 0踩 0收藏
文章评论
    发表评论

    个人资料

    • 昵称: 柯侧耳倾听者
    • 等级: 初级设计师
    • 积分: 2220
    • 代码: 64 个
    • 文章: 64 篇
    • 随想: 5 条
    • 访问: 43 次
    • 关注

    标签

    最新提问

      站长推荐