论坛首页 编程语言技术论坛

答复: 迅雷亲历面经:JAVA 笔试+上机+面试(完整面试题大讨论)

浏览 21607 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-12-01   最后修改:2011-01-26
C
引用
有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC…


引申了一下:

有n个线程,ID为0...n-1,在屏幕上循环打印m次012..n-1

用 c/pthread 实现

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>

#define GROUP_COUNT 100
#define GROUP_SIZE 4 

typedef struct {
	pthread_mutex_t mutex;
	pthread_cond_t cond;
	int index;
} syn_obj_t;

syn_obj_t syn_obj = {PTHREAD_MUTEX_INITIALIZER, 
	PTHREAD_COND_INITIALIZER, 0};

typedef struct {
	int flag;
} elem_t; 

void *
thread_routine(void *arg);

int
main(int argc, char** argv)
{
	elem_t elems[GROUP_SIZE];
	pthread_t pds[GROUP_SIZE];
	int i;

	printf("syn_obj.index = %d\n", syn_obj.index);

	for (i = 0; i < GROUP_SIZE; i++) {
		elems[i].flag = i;
		if ( (pthread_create(&pds[i], NULL, thread_routine, &elems[i])) != 0 ) {
			perror("pthread create");
			exit(-1);
		}
	}

	for (i = 0; i < GROUP_SIZE; i++) {
		pthread_join(pds[i], NULL);
	}

	pthread_mutex_destroy(&syn_obj.mutex);
	pthread_cond_destroy(&syn_obj.cond);

	printf("\nsyn_obj.index = %d\n", syn_obj.index);

	return 0;
}

void *
thread_routine(void *arg) {
	elem_t *elem = (elem_t *)arg;
	int i;
	for (i = 0; i < GROUP_COUNT; i++) {
		pthread_mutex_lock(&syn_obj.mutex);
		while ( (syn_obj.index % GROUP_SIZE) != elem->flag ) {
			pthread_cond_wait(&syn_obj.cond, &syn_obj.mutex);
	 	}
		printf("%d", elem->flag);
		if ( 0 == (syn_obj.index+1) % GROUP_SIZE ) {
			printf("\t");
		}
		syn_obj.index++;
		pthread_cond_broadcast(&syn_obj.cond);
		// may be cause deadlock 
		// pthread_cond_signal(&syn_obj.cond);
		pthread_mutex_unlock(&syn_obj.mutex);
		// sleep(1);
	}
	return NULL;
}

   发表时间:2009-12-04  
LZ分享得不错哈~
0 请登录后投票
   发表时间:2009-12-05   最后修改:2009-12-05
   贴一个Java的,实现可能和楼主的有些差别,输出A、B、C分别使用三个不同的线程类。不过原理都是一样,实现线程的顺序调度。判断条件,不满足的话,等待;接到通知以后,重新判断。
public class SequenceWork {

    private static Boolean[] abc = {false, false, true};

    public static void main(String[] args) {
        ThreadA a = new ThreadA();
        a.start();
        ThreadB b = new ThreadB();
        b.start();
        ThreadC c = new ThreadC();
        c.start();
    }

    static class ThreadA extends Thread {

        public void run() {
            while (true) {
                synchronized (abc) {
                    if (abc[2]) {
                        System.out.print("A");
                        abc[0] = true;
                        abc[2] = false;
                        abc.notifyAll();
                    } else {
                        try {
                            abc.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }

                }
            }

        }
    }

    static class ThreadB extends Thread {

        public void run() {
            while (true) {
                synchronized (abc) {
                    if (abc[0]) {
                        System.out.print("B");
                        abc[1] = true;
                        abc[0] = false;
                        abc.notifyAll();

                    } else {
                        try {
                            abc.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }

        }
    }

    static class ThreadC extends Thread {

        public void run() {
            while (true) {
                synchronized (abc) {
                    if (abc[1]) {
                        System.out.println("C");
                        abc[2] = true;
                        abc[1] = false;
                        abc.notifyAll();
                    } else {
                        try {
                            abc.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}
1 请登录后投票
   发表时间:2009-12-05  
shelocks 写道
   贴一个Java的,实现可能和楼主的有些差别,输出A、B、C分别使用三个不同的线程类。不过原理都是一样,实现线程的顺序调度。判断条件,不满足的话,等待;接到通知以后,重新判断。
public class SequenceWork {

    private static Boolean[] abc = {false, false, true};

    public static void main(String[] args) {
        ThreadA a = new ThreadA();
        a.start();
        ThreadB b = new ThreadB();
        b.start();
        ThreadC c = new ThreadC();
        c.start();
    }

    static class ThreadA extends Thread {

        public void run() {
            while (true) {
                synchronized (abc) {
                    if (abc[2]) {
                        System.out.print("A");
                        abc[0] = true;
                        abc[2] = false;
                        abc.notifyAll();
                    } else {
                        try {
                            abc.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }

                }
            }

        }
    }

    static class ThreadB extends Thread {

        public void run() {
            while (true) {
                synchronized (abc) {
                    if (abc[0]) {
                        System.out.print("B");
                        abc[1] = true;
                        abc[0] = false;
                        abc.notifyAll();

                    } else {
                        try {
                            abc.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }

        }
    }

    static class ThreadC extends Thread {

        public void run() {
            while (true) {
                synchronized (abc) {
                    if (abc[1]) {
                        System.out.println("C");
                        abc[2] = true;
                        abc[1] = false;
                        abc.notifyAll();
                    } else {
                        try {
                            abc.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

楼上的解法正点!
0 请登录后投票
   发表时间:2009-12-05   最后修改:2009-12-05
另外一个版本。。。
public class SequenceWork {   
	private static final int GROUP_SIZE=10;
	private static final int RUN_COUNT=4;
    private static boolean[] res = new boolean[GROUP_SIZE]; 
  
    public static void main(String[] args) {   
    	res[0]=true;
    	for(int i=0;i<GROUP_SIZE;i++){
    		new MyThread(i).start();   
    	}
    }   
  
    static class MyThread extends Thread {   
        private Integer id;
        private String name;
    	public MyThread(){}
        public MyThread(Integer id){
        	this.id=id;
        	this.name=id+" ";
        }
    	public void run() {  
        	int count=0;
        	if(id==GROUP_SIZE-1){
        		this.name+="\n";
        	}
            while (true) {   
                synchronized (res) {   
                    if (res[id]) {   
                        System.out.print(name);
                        ++count;
                        res[(id+1)%GROUP_SIZE] = true;   
                        res[id] = false;   
                        res.notifyAll();
                        if(count==RUN_COUNT){
                        	return;
                        }
                    } else {   
                        try {   
                            res.wait();   
                        } catch (InterruptedException ex) {   
                            ex.printStackTrace();   
                        }   
                    }   
  
                }   
            }   
  
        }   
    }   
}
0 请登录后投票
   发表时间:2009-12-06   最后修改:2009-12-06
jeye.bow 写道
引用
有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC…


引申了一下:

有n个线程,ID为0...n-1,在屏幕上循环打印m次012..n-1

用 c/pthread 实现

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>

/*......*/



void *
thread_routine(void *arg) {
	elem_t *elem = (elem_t *)arg;
	int i;
	for (i = 0; i < GROUP_COUNT; i++) {
		pthread_mutex_lock(&syn_obj.mutex);
		while ( (syn_obj.index % GROUP_SIZE) != elem->flag ) {
			pthread_cond_wait(&syn_obj.cond, &syn_obj.mutex);
	 	}
		printf("%d", elem->flag);
		if ( 0 == (syn_obj.index+1) % GROUP_SIZE ) {
			printf("\t");
		}
		syn_obj.index++;
		pthread_cond_broadcast(&syn_obj.cond);          /*A*/ 
		// may be cause deadlock 
		// pthread_cond_signal(&syn_obj.cond);     
		pthread_mutex_unlock(&syn_obj.mutex);         /*B*/
		// sleep(1);
	}
	return NULL;
}




写的不错,是校园招聘吗,如果现场能写成这样不错了

不过 这里的 A 和 B 需要掉个位置
因为pthread_cond_wait 不够原子
0 请登录后投票
   发表时间:2009-12-06  
easonfans 写道
shelocks 写道
   贴一个Java的,实现可能和楼主的有些差别,输出A、B、C分别使用三个不同的线程类。不过原理都是一样,实现线程的顺序调度。判断条件,不满足的话,等待;接到通知以后,重新判断。
public class SequenceWork {

    private static Boolean[] abc = {false, false, true};

    public static void main(String[] args) {
        ThreadA a = new ThreadA();
        a.start();
        ThreadB b = new ThreadB();
        b.start();
        ThreadC c = new ThreadC();
        c.start();
    }

    static class ThreadA extends Thread {

        public void run() {
            while (true) {
                synchronized (abc) {
                    if (abc[2]) {
                        System.out.print("A");
                        abc[0] = true;
                        abc[2] = false;
                        abc.notifyAll();
                    } else {
                        try {
                            abc.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }

                }
            }

        }
    }
//。。。。。。。。。。。。。

楼上的解法正点!


万一是线程池呢。。。。。。你的代码就吓死人了哈哈

0 请登录后投票
   发表时间:2009-12-06   最后修改:2009-12-06
sunzixun 写道
easonfans 写道
shelocks 写道
   贴一个Java的,实现可能和楼主的有些差别,输出A、B、C分别使用三个不同的线程类。不过原理都是一样,实现线程的顺序调度。判断条件,不满足的话,等待;接到通知以后,重新判断。
public class SequenceWork {

    private static Boolean[] abc = {false, false, true};

    public static void main(String[] args) {
        ThreadA a = new ThreadA();
        a.start();
        ThreadB b = new ThreadB();
        b.start();
        ThreadC c = new ThreadC();
        c.start();
    }

    static class ThreadA extends Thread {

        public void run() {
            while (true) {
                synchronized (abc) {
                    if (abc[2]) {
                        System.out.print("A");
                        abc[0] = true;
                        abc[2] = false;
                        abc.notifyAll();
                    } else {
                        try {
                            abc.wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }

                }
            }

        }
    }
//。。。。。。。。。。。。。

楼上的解法正点!


万一是线程池呢。。。。。。你的代码就吓死人了哈哈


  输出A、B、C是三个不同的任务,他们之间要以一种顺序化的顺序调度,而不是简单的在一个线程里输出不同的标志位。上面的示例代码代码是extends thread,你完全可以把它实现为Runnable。跟线程池有什么关系。
0 请登录后投票
   发表时间:2009-12-06  
我参照了下兄弟们写的,用的是JAVA5.0的ReentrantLock也写了一个:
大家一起一为鉴赏一下
调用类:FuLockThreadTest //用于线程ABC的调用实现
public class FuLockThreadTest {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// 加锁实现
new Thread(new FuLockThread(0), "A").start();// 注意线程命名
new Thread(new FuLockThread(1), "B").start();
new Thread(new FuLockThread(2), "C").start();
}
}
线程类:FuLockThread //用ReentrantLock加锁机制实现,注意在finally里面实现解锁
import java.io.IOException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class FuLockThread extends Thread {

private int id;
private static int count = 0;// 活学活用static类型
private int pcount;
private boolean mark = true;
private ReentrantLock lock;
private Condition condition;

public FuLockThread(int id) {
this.id = id;
lock = new ReentrantLock();
condition = lock.newCondition();
}

@Override
public void run() {
// TODO Auto-generated method stub
// 当前的count计数为id值,则进行输出
// 加锁实现

lock.lock();
try {// 加锁实现
while (mark) {
if (count % 3 == id) {
System.out.print(Thread.currentThread().getName());
count++;
pcount++;
condition.signalAll();
if (pcount == 10)
mark = false;
}
}
} finally {
if (count % 3 != id) {
try {
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else
lock.unlock();
}
}
}
0 请登录后投票
   发表时间:2009-12-06  
一种没有使用并发包的实现。遇到一个问题,lock对象如果直接用Integer会异常,封装成Lock类就可以了。
public class SequenceTask {

	private static volatile Lock lock = new Lock();

	private static String[] infos = { "A", "B", "C" };

	public static void main(String[] args) {
		for (int i = 0; i < infos.length; i++) {
			Thread thread = new Thread(new PrintTask(i));
			thread.start();
		}
	}

	static class Lock {
		private int flag = 0;

		public int getFlag() {
			return flag;
		}

		public void setFlag(int flag) {
			this.flag = flag;
		}
	}

	static class PrintTask implements Runnable {
		private int id;

		public PrintTask(int id) {
			this.id = id;
		}

		public void run() {
			while (true) {
				synchronized (lock) {
					if (lock.getFlag() == id) {
						System.out.print(infos[id]);
						lock.setFlag((id + 1) % infos.length);
						lock.notifyAll();
					} else {
						try {
							lock.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics