求解答,java中用多线程判断素数

Jay白色风车 2013-03-13 08:43:28
大家好,我是一个java菜鸟,今天学到多线程,求助大家,教我写个多线程实现判断一个数是否为素数的代码,希望有详细的注释。谢啦!
...全文
680 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
liujinxu212 2015-04-23
  • 打赏
  • 举报
回复
引用 11 楼 preferme 的回复:
计算机是一门实践科学,所以,我们一般都是比较务实的人。 楼主的这个问题,就经验而谈,没有实际意义。 多线程技术的应用场景,主要就两个方面:一、CPU密集型运算;二、异步阻塞处理。 楼主求一个数是否是素数,说实话,真没必要多线程。耗时时间长,占用内存多,编程复杂度相对要大。 既然楼主是为了学习而学习,那么,我也只能用笨办法来解决了。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;


public class PrimeUtil {

	public static final int QUEUE_SIZE = 100;
	private static final Operand POISON = new Operand();
	private BlockingQueue<Operand> operands = new LinkedBlockingQueue<PrimeUtil.Operand>(QUEUE_SIZE);
	private BlockingQueue<Operand> results  = new LinkedBlockingQueue<PrimeUtil.Operand>(QUEUE_SIZE);
	private boolean running = false;
	private long number;
	
	public PrimeUtil(long number) {
		this.number = number;
	}

	static class Operand{
		long dividend;	//被除数
		long divisor;	//除数
		long remainder;	//余数
	}
	
	class Producer extends Thread{
		public void run(){
			try {
				for(int i=2;running && i<number;i++){
					Operand o = new Operand();
					o.dividend = number;
					o.divisor  = i;
					operands.put(o);
				}
				operands.put(POISON);
			} catch (InterruptedException e) {
			}
		}
	}
	
	class Consumer extends Thread{
		public void run(){
			try {
				while(running){
					Operand o = operands.take();
					if(o==POISON){
						operands.put(o);
						results.put(o);
						break;
					}
					o.remainder = o.dividend % o.divisor;
					results.put(o);
				}
			} catch (InterruptedException e) {
			}
		}
	}
	
	private boolean isPrime(){
		Producer producer = new Producer();
		Consumer consumer = new Consumer();
		running = true;
		producer.start();
		consumer.start();
		try {
			while(running){
				Operand o = results.take();
				if(o==POISON){
					running = false;
					return true;
				}
				if(o.remainder==0){
					running = false;
				}
			}
		} catch (InterruptedException e) {
		}
		return false;
	}
	
	public static boolean isPrime(long number){
		if(number==1 || number==2)return true;
		return new PrimeUtil(number).isPrime();
	}
	
	/**
	 * 测试用例
	 */
	public static void main(String[] args) {
		System.out.println(isPrime(5));
	}

}
有没有linux c 版本的呢
冰思雨 2014-06-10
  • 打赏
  • 举报
回复
计算机是一门实践科学,所以,我们一般都是比较务实的人。 楼主的这个问题,就经验而谈,没有实际意义。 多线程技术的应用场景,主要就两个方面:一、CPU密集型运算;二、异步阻塞处理。 楼主求一个数是否是素数,说实话,真没必要多线程。耗时时间长,占用内存多,编程复杂度相对要大。 既然楼主是为了学习而学习,那么,我也只能用笨办法来解决了。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;


public class PrimeUtil {

	public static final int QUEUE_SIZE = 100;
	private static final Operand POISON = new Operand();
	private BlockingQueue<Operand> operands = new LinkedBlockingQueue<PrimeUtil.Operand>(QUEUE_SIZE);
	private BlockingQueue<Operand> results  = new LinkedBlockingQueue<PrimeUtil.Operand>(QUEUE_SIZE);
	private boolean running = false;
	private long number;
	
	public PrimeUtil(long number) {
		this.number = number;
	}

	static class Operand{
		long dividend;	//被除数
		long divisor;	//除数
		long remainder;	//余数
	}
	
	class Producer extends Thread{
		public void run(){
			try {
				for(int i=2;running && i<number;i++){
					Operand o = new Operand();
					o.dividend = number;
					o.divisor  = i;
					operands.put(o);
				}
				operands.put(POISON);
			} catch (InterruptedException e) {
			}
		}
	}
	
	class Consumer extends Thread{
		public void run(){
			try {
				while(running){
					Operand o = operands.take();
					if(o==POISON){
						operands.put(o);
						results.put(o);
						break;
					}
					o.remainder = o.dividend % o.divisor;
					results.put(o);
				}
			} catch (InterruptedException e) {
			}
		}
	}
	
	private boolean isPrime(){
		Producer producer = new Producer();
		Consumer consumer = new Consumer();
		running = true;
		producer.start();
		consumer.start();
		try {
			while(running){
				Operand o = results.take();
				if(o==POISON){
					running = false;
					return true;
				}
				if(o.remainder==0){
					running = false;
				}
			}
		} catch (InterruptedException e) {
		}
		return false;
	}
	
	public static boolean isPrime(long number){
		if(number==1 || number==2)return true;
		return new PrimeUtil(number).isPrime();
	}
	
	/**
	 * 测试用例
	 */
	public static void main(String[] args) {
		System.out.println(isPrime(5));
	}

}
wwwcomy 2014-06-10
  • 打赏
  • 举报
回复
嗷。。 推荐个帖子 http://blog.csdn.net/program_think/article/details/7032600/ 其实这种问题好多都归于数学问题, 用多线程是要看场景的
rumlee 2014-06-10
  • 打赏
  • 举报
回复
这是为了学习多线程而用多线程写,建议采用线程池的方式,否则性能下降的太厉害。 做这种事情,虽然不管怎么优化,都不可能有单线程效率高。但是用线程池比单纯用多线程解决可能稍微要好一点。
RICHEER COCA 2014-06-10
  • 打赏
  • 举报
回复
引用 11 楼 preferme 的回复:
计算机是一门实践科学,所以,我们一般都是比较务实的人。 楼主的这个问题,就经验而谈,没有实际意义。 多线程技术的应用场景,主要就两个方面:一、CPU密集型运算;二、异步阻塞处理。 楼主求一个数是否是素数,说实话,真没必要多线程。耗时时间长,占用内存多,编程复杂度相对要大。 既然楼主是为了学习而学习,那么,我也只能用笨办法来解决了。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;


public class PrimeUtil {

	public static final int QUEUE_SIZE = 100;
	private static final Operand POISON = new Operand();
	private BlockingQueue<Operand> operands = new LinkedBlockingQueue<PrimeUtil.Operand>(QUEUE_SIZE);
	private BlockingQueue<Operand> results  = new LinkedBlockingQueue<PrimeUtil.Operand>(QUEUE_SIZE);
	private boolean running = false;
	private long number;
	
	public PrimeUtil(long number) {
		this.number = number;
	}

	static class Operand{
		long dividend;	//被除数
		long divisor;	//除数
		long remainder;	//余数
	}
	
	class Producer extends Thread{
		public void run(){
			try {
				for(int i=2;running && i<number;i++){
					Operand o = new Operand();
					o.dividend = number;
					o.divisor  = i;
					operands.put(o);
				}
				operands.put(POISON);
			} catch (InterruptedException e) {
			}
		}
	}
	
	class Consumer extends Thread{
		public void run(){
			try {
				while(running){
					Operand o = operands.take();
					if(o==POISON){
						operands.put(o);
						results.put(o);
						break;
					}
					o.remainder = o.dividend % o.divisor;
					results.put(o);
				}
			} catch (InterruptedException e) {
			}
		}
	}
	
	private boolean isPrime(){
		Producer producer = new Producer();
		Consumer consumer = new Consumer();
		running = true;
		producer.start();
		consumer.start();
		try {
			while(running){
				Operand o = results.take();
				if(o==POISON){
					running = false;
					return true;
				}
				if(o.remainder==0){
					running = false;
				}
			}
		} catch (InterruptedException e) {
		}
		return false;
	}
	
	public static boolean isPrime(long number){
		if(number==1 || number==2)return true;
		return new PrimeUtil(number).isPrime();
	}
	
	/**
	 * 测试用例
	 */
	public static void main(String[] args) {
		System.out.println(isPrime(5));
	}

}
学习了
vnvlyp 2014-06-10
  • 打赏
  • 举报
回复
写了一个多小时,调试了一晚上,应该没有问题了,支持大于等于2的所有long型数的判断,线程数选择要合理,小于int最大值的数一个线程就够了,多了没有帮助,超大的数也不要多于你的CPU核心数,不然反倒会更慢。
public class MultiThreadedIsPrime {
	public static void main(String[] args) {
		testWithASingleNumber();
		
		findPrimeNumbers();
	}
	
	public static void findPrimeNumbers() {
		int count = 0, threads = 2;
		long from = 5000, to = 10000;
		
		for (long i = from; i <= to; i++) {
			if (isPrime(i, threads)) {
				count++;
			}
		}
		
		System.out.println("There are " + count + 
				" prime numbers on the interval [" + from +
				"," + to + "]");
	}
	
	public static void testWithASingleNumber() {
		long num = 9223372036854775783L;
		int threads = 2;
		
		System.out.println("Checking if " + num + " is a prime number.");
		
		long time = System.currentTimeMillis();
		if (isPrime(num, threads)) {
			System.out.println(num + " is a prime number.");
		} else {
			System.out.println(num + " is not a prime number.");
		}
		time = System.currentTimeMillis() - time;
		System.out.println("Time consumed: " + time);
	}
	
	public static boolean isPrime(long n, int threads) {
		if (threads <= 0) {
			throw new IllegalArgumentException("Illegal number of threads.");
		}
		if (n <= 1) {
			throw new IllegalArgumentException("Illegal number.");
		}
		
		if (n <= 3 || n == 5 || n == 7) return true;
		if ((n & 1) == 0 || n % 3 == 0 || n % 5 == 0) return false;
		
		long sqrt = (long)Math.sqrt(n) + 1;
		long interval = (((sqrt - 7) / 30 + 1) / threads) * 30;
		
		if (interval == 0) {
			throw new IllegalArgumentException("Too many threads.");
		}
		
		IntervalChecker[] checkers = new IntervalChecker[threads];
		SharedMark mark = new SharedMark(threads);
		
		if (threads == 1) {
			checkers[0] = new IntervalChecker(n, 7, sqrt, mark);
		} else {
			checkers[0] = new IntervalChecker(n, 7, interval + 1, mark);
			for (int i = 1; i < threads - 1; i++) {
				checkers[i] = new IntervalChecker(n, interval * i + 7, 
						interval * (i + 1) + 1, mark);
			}
			checkers[threads - 1] = new IntervalChecker(n, interval + 7, sqrt, mark);
		}
		
		for (int i = 0; i < threads; i++) {
			new Thread(checkers[i]).start();
		}
		
		synchronized (mark.lock) {
			do {
				try {
					mark.lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
			} while (mark.runningThreads > 0);
		}
		
		return mark.unknown;
	}
	
	static class IntervalChecker implements Runnable {
		long n, from, to;
		final SharedMark mark;
		
		IntervalChecker(long n, long from, long to, SharedMark mark) {
			this.n = n;
			this.from = from;
			this.to = to;
			this.mark = mark;
		}
		
		@Override
		public void run() {
			final long[] steps = {4, 2, 4, 2, 4, 6, 2, 6};
			int j = 0;
			
			for (long i = from; mark.unknown && i <= to; i += steps[j &= 7], j++) {
				if (n % i == 0) {
					//System.out.println("Divisible by " + i);
					
					mark.unknown = false;
					break;
				}
			}
			
			synchronized (mark.lock) {
				mark.runningThreads--;
				mark.lock.notify();
			}
		}
		
	}
	
	static class SharedMark {
		boolean unknown;
		final Object lock;
		int runningThreads;
		SharedMark(int threads) {
			unknown = true;
			lock = new Object();
			runningThreads = threads;
		}
	}
}
woshiyexinjie 2014-06-09
  • 打赏
  • 举报
回复
Jay白色风车 2014-06-09
  • 打赏
  • 举报
回复
Jay白色风车 2013-05-07
  • 打赏
  • 举报
回复
我的问题还是没得好解决,不少人答非所问!哎。。。。。。。
快乐的2 2013-03-14
  • 打赏
  • 举报
回复
首先取区间3-X^1/2,然后把区间按线程数量分段 然后各个线程运行指定区间的X%n,如果全部线程都不能整除,则是素数,返回主线程由主线程查看判断结果
龙四 2013-03-14
  • 打赏
  • 举报
回复
一个数,用啥多线程。判断一堆数还差不多
yanxing2012 2013-03-13
  • 打赏
  • 举报
回复
没有必要用多线程,多线程会有一些开销,多线程一般用在堵塞的程序

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧