`
jsjzhou
  • 浏览: 27974 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

一道java多线程笔试上机题

阅读更多

   上个星期我到诚迈科技参加面试.面试完毕后面试官让我把笔试卷上的一道多线程题在计算机上编程实现.题目如下:

四个线程a,b,c,d. 线程a,b对变量i加一. 线程c,d对变量i减去一.四个线程顺序执行, 每个线程每次只执行一次.i的初始值为0, 打印结果0 1 2 1 0 1 2 1 0 1 2...

   这道题还是有一定的难度的. 因为要求顺序执行. 不能简单用同步.

   经考虑,我决定用一个队列来对四个线程顺序调度.代码如下:

package org.jenfer.struts2demo.web.struts2.action;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 四个线程a,b,c,d. 线程a,b对变量i加一.
 * 线程c,d对变量i减去一.四个线程顺序执行,
 * 每个线程每次只执行一次.i的初始值为0,
 * 打印结果0 1 2 1 0 1 2 1 0 1 2... 
 * 
 * @author 武汉科技大学08级研究生周剑华
 *
 */
public class MultiThreadTest {
	//variable i 
	private int i=0;
	//queue to control thread invoke
	private BlockingQueue<Integer> queue=new LinkedBlockingQueue<Integer>();
	
	public MultiThreadTest() {
		queue.offer(1);
		queue.offer(2);
		queue.offer(3);
		queue.offer(4);
	}
	
	public synchronized void inc(int con) throws InterruptedException{
		while(true){
			int c=queue.peek();
			if(c==con){
				break;
			}else{
				notifyAll();
				wait();
			}
		}
		
		queue.offer(queue.take());
		
		i++;
		System.out.println(Thread.currentThread().getName()+",i="+i);
	}
	
	public synchronized void dec(int con) throws InterruptedException{
		while(true){
			int c=queue.peek();
			if(c==con){
				break;
			}else{
				notifyAll();
				wait();
			}
		}
		
		queue.offer(queue.take());
		i--;
		System.out.println(Thread.currentThread().getName()+",i="+i);
	}
	
	private class IncThread implements Runnable{
		private int condition;
		public IncThread(int condition) {
			this.condition=condition;
		}
		public void run() {
			while(true){
				try {
					inc(condition);
				} catch (InterruptedException e) {
					System.err.println(Thread.currentThread().getName()+" exit now");
					break;
				}
			}
		}
	}
	
	private class DecThread implements Runnable{
		private int condition;
		public DecThread(int condition) {
			this.condition=condition;
		}
		public void run() {
			while(true){
				try {
					dec(condition);
				} catch (InterruptedException e) {
					System.err.println(Thread.currentThread().getName()+" exit now");
					break;
				}
			}
		}
	}
	
	public static void main(String[] args) {
		MultiThreadTest test=new MultiThreadTest();
		ExecutorService exec=Executors.newFixedThreadPool(4);
		exec.submit(test.new IncThread(1));
		exec.submit(test.new IncThread(2));
		exec.submit(test.new DecThread(3));
		exec.submit(test.new DecThread(4));
		
		exec.shutdown();
	}
}

 

分享到:
评论
9 楼 leoricxu 2014-06-25  
package com.thread.test;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
*  重新用队列写了下
* @author Administrator
*
*/
public class Task4Test2 {
public Task4Test2() {
print();
}

public static void main(String[] args) throws InterruptedException {
final Task4Test2 test = new Task4Test2();
test.queue1.put("start");

Thread a = new Thread(new Runnable() {
public void run() {
while (true) {
try {
test.queue1.take();
test.increment();
test.queue2.put("a");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "a");

Thread b = new Thread(new Runnable() {
public void run() {
while(true){
try {
test.queue2.take();
test.increment();
test.queue3.put("b");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "b");

Thread c = new Thread(new Runnable() {
public void run() {
while(true){
try {
test.queue3.take();
test.decrement();
test.queue4.put("c");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "c");

Thread d = new Thread(new Runnable() {
public void run() {
while(true){
try {
test.queue4.take();
test.decrement();
test.queue1.put("d");
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}, "d");
a.start();
b.start();
c.start();
d.start();
}

public void decrement() {
index--;
print();
}

public void increment() {
index++;
print();
}

public void print() {
System.out.println(Thread.currentThread().getName() +" "+index);
}

private int index;
private BlockingQueue<String> queue1 = new LinkedBlockingQueue<String>(1);
private BlockingQueue<String> queue2 = new LinkedBlockingQueue<String>(1);
private BlockingQueue<String> queue3 = new LinkedBlockingQueue<String>(1);
private BlockingQueue<String> queue4 = new LinkedBlockingQueue<String>(1);
}
8 楼 leoricxu 2014-06-25  
最近在学习多线程。
package com.thread.test;

import java.util.concurrent.Semaphore;

public class Task4Test {
private static Semaphore semp = new Semaphore(1);

public static void main(String args[]) throws InterruptedException {
final Task4Test number = new Task4Test();
while(true){
Thread a = new Thread(new Runnable() {
public void run() {
number.increment();


}
},"a");

Thread b = new Thread(new Runnable() {
public void run() {

number.increment();

}
},"b");

Thread c = new Thread(new Runnable() {
public void run() {
number.minus();

}
},"c");

Thread d = new Thread(new Runnable() {
public void run() {

number.minus();

}
},"d");
a.start();
a.join();
b.start();
b.join();
c.start();
c.join();
d.start();
d.join();


}
}

public synchronized void minus() {
try {
semp.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (index > 0) {
--index;
print();
semp.release();
} else {
semp.release();
}

}

public synchronized void increment() {
try {
semp.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (index < 2) {
++index;
print();
semp.release();
} else {
semp.release();
}

}

public Task4Test() {
System.out.println(index);
}

public void print() {
System.out.println(Thread.currentThread().getName()+"   "+index);
}

private int index = 0;
}
7 楼 funnyone 2013-10-17  
	private static volatile int target=0;
	private static volatile int count=0;
	private static final Object LOCk=new Object();
	
	public static void main(String[] args) throws Exception {
		for(char i='a';i<='d';i=(char)(i+1)){
			final char temp=i;
			new Thread(new Runnable() {
				public void run() {
					while(true){
						if (count%4==(int)temp-(int)'a') {
							synchronized (LOCk) {
								if (count%4==(int)temp-(int)'a') {
									++count;
									if (temp=='a'||temp=='b') {
										++target;
									}else {
										--target;
									}
								}
								System.err.println(temp+":"+target);
							}
						}
					}
				}
			}).start();
		}
	}
6 楼 yan465942872 2011-08-30  
自己写的。。

public class Test {  
	public static void main(String[] args) {
		
		final ShareData shareData = new ShareData();

		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					shareData.increase(0);
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					shareData.increase(1);
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					shareData.decrease(2);
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					shareData.decrease(3);
				}
			}
		}).start();
		
	}
} 

class ShareData {
	
	int i = 0;
	int j = 0;
	
	public synchronized void increase(int threadIndex) {
		
		while(j != threadIndex) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("Thread " + j + ": i = " + i);
		i++;
		j = (j + 1) % 4;
		notifyAll();
	}
	
	public synchronized void decrease(int threadIndex) {
		while(j != threadIndex) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("Thread " + j + ": i = " + i);
		i--;
		j = (j + 1) % 4;
		notifyAll();
	}
	
}
5 楼 jsjzhou 2011-06-05  
另外我提供一个简单的方法:
/**
*
* @author 武汉科技大学 周剑华
*
*/
public class ThreadTest {
private static final int THREAD_NUM = 4;
private int invoder = 0;
private int i = 0;

public synchronized void add(final int threadIndex) throws Exception {
while (threadIndex != invoder) {
wait();
}
invoder = (invoder + 1) % THREAD_NUM;
System.out.println("Thread " + threadIndex + ": i=" + i);
i++;
notifyAll();
}

public synchronized void sub(final int threadIndex) throws Exception {
while (threadIndex != invoder) {
wait();
}
invoder = (invoder + 1) % THREAD_NUM;
System.out.println("Thread " + threadIndex + ": i=" + i);
i--;
notifyAll();
}

private class Inc extends Thread {
private final int index;

public Inc(int index) {
this.index = index;
}

@Override
public void run() {
try {
while (true) {
add(index);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

private class Dec extends Thread {
private final int index;

public Dec(int index) {
this.index = index;
}

@Override
public void run() {
try {
while (true) {
sub(index);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {
ThreadTest test = new ThreadTest();
test.new Inc(0).start();
test.new Inc(1).start();
test.new Dec(2).start();
test.new Dec(3).start();
}
}
4 楼 jsjzhou 2010-11-15  
shengren0 写道
楼主的代码运行结果跟预期不一致

在你的环境运行结果是什么啊?请赐教。
3 楼 shengren0 2010-10-30  
楼主的代码运行结果跟预期不一致
2 楼 ws715 2010-08-03  
楼下的程序也只能叫单线程吧
1 楼 253317239 2010-07-20  
/**
*  @作者: cz
*  2010-7-20  下午02:03:51
*  TODO:四个线程a,b,c,d. 线程a,b对变量i加一. 线程c,d对变量i减去一.
*  四个线程顺序执行, 每个线程每次只执行一次.i的初始值为0,
*   打印结果0 1 2 1 0 1 2 1 0 1 2...
*/

public class MutilThreadTest implements Runnable{
   static int i=0;
     public static void runThreadA(){
i++;
System.out.print(i);
try{
Thread.sleep(100);
}catch(Exception e){
e.printStackTrace();
}
   }
     public static void runThreadB(){
i--;
System.out.print(i);
try{
Thread.sleep(100);
}catch(Exception e){
e.printStackTrace();
}
    }
 
/**
* @param args
*/
public static void main(String[] args) {
System.out.print(0);
try{
while(true){
       new Thread(new MutilThreadTest()).start();
       Thread.sleep(400);
}
}catch(Exception e){
e.printStackTrace();
}
}

/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run() {
try{
new MutilThreadTest().runThreadA();
new MutilThreadTest().runThreadA();
new MutilThreadTest().runThreadB();
new MutilThreadTest().runThreadB();
}catch(Exception e){
e.printStackTrace();
}

}
}

相关推荐

    Java多线程设计模式上传文件

    Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...

    java多线程读取文件

    Java多线程读大文件 java多线程写文件:多线程往队列中写入数据

    java多线程ppt

    java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题

    java 多线程操作数据库

    一个java 多线程操作数据库应用程序!!!

    java多线程的讲解和实战

    详细的讲解了java多线程的原理,并配有代码进行实战,适合java初学者和想对多线程有进一步了解的人。

    Java多线程练习题

    这是对Java多线程的一些相关练习题 包括选择 填空 简答 编程等题型

    java多线程经典案例

    java多线程经典案例,线程同步、线程通信、线程阻塞等经典案例

    Java多线程知识点总结

    该文档总结了Java多线程相关的知识点,分享给大家,简单易懂!

    java多线程查询数据库

    java多线程并发查询数据库,使用线程池控制分页,并发查询。

    java多线程处理数据库数据

    java多线程处理数据库数据,使用并发包,无框架,可批量处数据库数据,进行增删改。。等等操作。

    多线程启动.java多线程启动.java多线程启动.java

    多线程启动.java多线程启动.java多线程启动.java多线程启动.java

    JAVA多线程练习题答案。

    JAVA多线程练习题的答案。都是一些基本的练习题。对初学者有帮助

    java多线程实现大批量数据导入源码

    java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制

    JAVA多线程端点续传下载

    JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载...

    java多线程,对多线程,线程池进行封装,方便使用

    java多线程,对多线程,线程池进行封装,方便使用

    java多线程模拟队列实现排队叫号

    java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号 java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号

    Java多线程编程实战指南(核心篇)

    Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...

    java多线程核心技术

    资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如...

    java多线程处理大数据

    java多线程处理大数据,可根据配置的线程数,任务去调度处理

    java多线程通信图解

    java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,这时B线程再从主线程获取该变量的值,这样就实现了...

Global site tag (gtag.js) - Google Analytics