有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC…

fantasy0126 2010-12-13 10:56:23
引用迅雷面试题
http://topic.csdn.net/u/20091129/21/4bbf398d-431a-4f8e-accc-b8de6572b8af.html?1357


我写了一个实现,线程用得不熟,有人能给出一个更好些的实现吗?


class A extends Thread {
public A(String name){super(name);}
@Override
public void run() {

System.out.println("id-->"+this.getId()+"name-->"+getName());

}
}

class B extends Thread {

private A a;

public B(A a,String name) {
super(name);
this.a = a;
}

@Override
public void run() {
try {
a.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("id-->"+this.getId()+"name-->"+getName());

}
}

class C extends Thread {

private B b;

public C(B b,String name) {
super(name);
this.b = b;
}

@Override
public void run() {
try {
b.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("id-->"+this.getId()+"name-->"+getName());

}
}

public class ConABC10 {

public static void main(String[] args) {

long s=System.currentTimeMillis();
int i = 0;

while (i++ < 10) {

A a = new A("A");
B b = new B(a,"B");
C c = new C(b,"C");

a.start();
b.start();
c.start();

}
System.out.println(System.currentTimeMillis()-s);
}
}
...全文
537 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
ppkk315 2011-07-07
  • 打赏
  • 举报
回复
4楼的答案貌似有死锁可能。
加上一行
}else {
try{
//add
synObj.notifyAll();
synObj.wait();
}catch(Exception e){
e.printStackTrace();
}
}
fantasy0126 2010-12-13
  • 打赏
  • 举报
回复
以下是我自己写的一个改进方法,和4楼9楼相比,差距是明显的.
1)除long,double外的primitive类型应该读和写都是原子操作.再加上volatile关键字应该没有问题 的
2)谁能找找原理上有没有什么BUG之类的,不胜感谢

class A extends Thread {

public A(String name) {
super(name);
}

@Override
public void run() {
while (true) {
if (ConABC10.times == 10) {
break;
} else if (ConABC10.flag == 'A') {
System.out.println("id-->" + this.getId() + "name-->" + getName());
ConABC10.flag = 'B';
} else {
yield();
}
}
}
}

class B extends Thread {

public B( String name) {
super(name);

}

@Override
public void run() {

while (true) {
if (ConABC10.times == 10) {

break;
} else if (ConABC10.flag == 'B') {
System.out.println("id-->" + this.getId() + "name-->" + getName());
ConABC10.flag = 'C';
} else {
yield();
}
}

}
}

class C extends Thread {


public C(String name) {
super(name);

}

@Override
public void run() {
while (true) {
if (ConABC10.times == 10) {
System.out.println(System.currentTimeMillis() - ConABC10.s);
break;
} else if (ConABC10.flag == 'C') {
System.out.println("id-->" + this.getId() + "name-->" + getName());
ConABC10.flag = 'A';
ConABC10.times++;
} else {
yield();
}
}


}
}

public class ConABC10 {

public static volatile char flag = 'A';
public static volatile int times = 0;
public static volatile long s;
public static void main(String[] args) {

s = System.currentTimeMillis();
int i = 0;


A a1 = new A("A");
B b1 = new B("B");
C c1 = new C("C");


a1.start();
b1.start();
c1.start();



}
}
fantasy0126 2010-12-13
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 pywepe 的回复:]

引用楼主 fantasy0126 的回复:
引用迅雷面试题
http://topic.csdn.net/u/20091129/21/4bbf398d-431a-4f8e-accc-b8de6572b8af.html?1357


我写了一个实现,线程用得不熟,有人能给出一个更好些的实现吗?


class A extends Thread {
public A(String n……
[/Quote]

虽然原理暂时还不明白,但一看就知道是个concurrent包的高人
fantasy0126 2010-12-13
  • 打赏
  • 举报
回复
4楼,我只想说,佩服,你的代码太好啦!
1)java.util.concurrent.atomic.AtomicInteger这个类是亮点.一直觉得java se 5.0的concurrent包很强大,却一直不是熟悉,今天我想是时候找本书学习一下了.
这个类解决了传统写法的一些问题 .我的体会是.你各个线程之间如果共享的是int,char等primitive类型肯定是不行的,因为它们不是对象.2)Integer,Character包装类也是不成的,因为他们是不变类型,同理String 类型也是不成的,因为不变类型,改变内容返回的是新的地址,而不是在原有地址上.3)自己写个类吧,总觉得也不是那么回事
2) 构造函数写的很灵活
3) run方法写得也帅气.看来对同步的理解很深入.
[Quote=引用 4 楼 yaoweijq 的回复:]

Java code
import java.util.concurrent.atomic.AtomicInteger;

public class Print extends Thread{
private AtomicInteger synObj;
private int count;
private String s;
private int flag;
……
[/Quote]
pywepe 2010-12-13
  • 打赏
  • 举报
回复
[Quote=引用楼主 fantasy0126 的回复:]
引用迅雷面试题
http://topic.csdn.net/u/20091129/21/4bbf398d-431a-4f8e-accc-b8de6572b8af.html?1357


我写了一个实现,线程用得不熟,有人能给出一个更好些的实现吗?


class A extends Thread {
public A(String name){super(name);}
……
[/Quote]

以前做过,运用concurrent包

http://topic.csdn.net/u/20100801/12/e5265ef6-eaed-4cf7-a524-1e5592fa5967.html

package pcenshao.thread; import java.util.concurrent.Semaphore; public class SemaphoreABC { static class T extends Thread{ Semaphore me; Semaphore next; public T(String name,Semaphore me,Semaphore next){ super(name); this.me = me; this.next = next; } @Override public void run(){ for(int i = 0 ; i < 10 ; i ++){ try { me.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.getName()); next.release(); } } } public static void main(String[] args) { Semaphore aSem = new Semaphore(1); Semaphore bSem = new Semaphore(0); Semaphore cSem = new Semaphore(0); T a = new T("A",aSem,bSem); T b = new T("B",bSem,cSem); T c = new T("C",cSem,aSem); a.start(); b.start(); c.start(); } }



fantasy0126 2010-12-13
  • 打赏
  • 举报
回复

思路也很好.但是5.0前的传统方法.共享lock的是一个对象lock,数数的用g_index
一点个人见解: 1) g_index和g_count 应该加上volatile关键声明吧,要不虚拟机优化的原因,run方法内会有本地拷贝?2)wait()在while循环中,这是很好的,但外面套了个for1-10总觉得有些怪异

[Quote=引用 6 楼 zhuzeitou 的回复:]

似乎思路和#4的似乎差不多

再修改下,避免一点问题

Java code
public class TestABC {

public static void main(String[] args) throws Exception {
System.out.println("start");
Thread a = new Thread(new……
[/Quote]
fantasy0126 2010-12-13
  • 打赏
  • 举报
回复
,说得很好,确实我的代码和1楼的代码是有问题 的
[Quote=引用 3 楼 yaoweijq 的回复:]

...
thread.join();
等待该线程终止。。。
这和顺序打印有何区别?
引用 1 楼 caofaping 的回复:
Java code

public class TestABC {

public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
……
[/Quote]
zhuzeitou 2010-12-13
  • 打赏
  • 举报
回复
似乎思路和#4的似乎差不多

再修改下,避免一点问题

public class TestABC {

public static void main(String[] args) throws Exception {
System.out.println("start");
Thread a = new Thread(new Runner("A"));
Thread b = new Thread(new Runner("B"));
Thread c = new Thread(new Runner("C"));
a.start();
b.start();
c.start();
a.join();
b.join();
c.join();
System.out.println("finish");
}
}

class Runner implements Runnable {
private String name;
private int index;

private static int g_index = 0;
private static int g_count = 0;

private static final Object lock = new Object();

public Runner(String name) {
this.name = name;
this.index = g_count++;
}

public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
while (g_index != index) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name);
g_index = (g_index + 1) % g_count;
lock.notifyAll();
}
}
}
}
zhuzeitou 2010-12-13
  • 打赏
  • 举报
回复
public class TestABC {

public static void main(String[] args) throws Exception {
Thread a = new Thread(new Runner("A", 0));
Thread b = new Thread(new Runner("B", 1));
Thread c = new Thread(new Runner("C", 2));
a.start();
b.start();
c.start();
a.join();
b.join();
c.join();
}
}

class Runner implements Runnable {
private String name;
private int index;

private static int g_index = 0;
private static int g_count = 0;

private static final Object lock = new Object();

public Runner(String name, int index) {
this.name = name;
this.index = index;
g_count++;
}

public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
while (g_index != index) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(name);
g_index = (g_index + 1) % g_count;
lock.notifyAll();
}
}
}
}
yaoweijq 2010-12-13
  • 打赏
  • 举报
回复
import java.util.concurrent.atomic.AtomicInteger;

public class Print extends Thread{
private AtomicInteger synObj;
private int count;
private String s;
private int flag;
private int total = 0;

public Print(int count,AtomicInteger atomicInteger,String s,int flag) {
this.count = count;
this.synObj = atomicInteger;
this.s = s;
this.flag = flag;
}
public void run() {
while(true) {
synchronized(synObj) {
if(synObj.intValue()%3 == flag) {
total++;
synObj.set(synObj.intValue()+1);
System.out.println(s);
synObj.notifyAll();
if(total == count) {
break;
}
}else {
try{
synObj.wait();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
public static void main(String[]args) throws Exception {
AtomicInteger synObj = new AtomicInteger(0);
Print a = new Print(10,synObj,"A",0);
Print b = new Print(10,synObj,"B",1);
Print c = new Print(10,synObj,"C",2);
a.start();
b.start();
c.start();
}
}

这个可供参考。。。
yaoweijq 2010-12-13
  • 打赏
  • 举报
回复
...
thread.join();
等待该线程终止。。。
这和顺序打印有何区别?
[Quote=引用 1 楼 caofaping 的回复:]
Java code

public class TestABC {

public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
Thread a = new Thread(new Runner("A"));
……
[/Quote]
fantasy0126 2010-12-13
  • 打赏
  • 举报
回复
感 谢.很好,速度好快
[Quote=引用 1 楼 caofaping 的回复:]

Java code

public class TestABC {

public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
Thread a = new Thread(new Runner("A"));
……
[/Quote]
caofaping 2010-12-13
  • 打赏
  • 举报
回复

public class TestABC {

public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
Thread a = new Thread(new Runner("A"));
a.start();
a.join();
Thread b = new Thread(new Runner("B"));
b.start();
b.join();
Thread c = new Thread(new Runner("C"));
c.start();
c.join();
System.out.println();
}
}

}

class Runner implements Runnable {
private String name;

public Runner(String name) {
this.name = name;
}

public void run() {
System.out.println(name);
}
}


62,614

社区成员

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

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