论坛首页 Java企业应用论坛

java 多线程小练

浏览 9420 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-05-12   最后修改:2011-05-12
在网上看到这样一道试题,关于多线程的,拿来小练一下
题目:有一个南北向的桥,只能容纳一个人,现桥的两边分别有10人和12人,编制一个多线程序让这些人到达对岸,每个人用一个线程表示,桥为共享资源。在过桥的过程中显示谁在过桥及其走向。

以下是我的代码
package test;

public class MyThread3 extends Thread {

	private String name;
	private String direction;

	public MyThread3(String name, String direction) {
		this.direction = direction;
		this.name = name;
		System.out.println(direction + "方的" + name + "开始过桥...");
	}

	public synchronized void run() {
		try {
			Thread.currentThread().sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(this.direction + "方的" + this.name + "过桥完成!"+"---"+Thread.currentThread().getName());
	}

	public static void main(String[] args) throws InterruptedException {
		MyThread3[] ths = new MyThread3[12];
		int i = 0;
		boolean flag = true;
		while (i <ths.length) {
			if (i < 10)
				ths[i] = new MyThread3("第" + (i+1) + "个人",flag == false ? "北" : "南");
			else
				ths[i] = new MyThread3("第" + (i+1) + "个人", "南");
			ths[i].start();
			ths[i].join();
			ths[i].sleep(1000);
			flag = !flag;
			if (flag == true||i>=10)
				i++;
		}
	}
}


对于synchronized 关键字用法还没完全搞懂,在run中可有可无的
   发表时间:2011-05-12  
说通俗点,synchronized 是用来让线程在访问同一资源时排队,防止造成冲突
0 请登录后投票
   发表时间:2011-05-12   最后修改:2011-05-12
写了一个,你可以参考一下

package test;

public class TheBridge {

	public static void main(String[] args) {
		Bridge bridge = new Bridge();
		for (int i = 0; i < 22; i++) {
			if (i < 10) {
				new PersonCrossBridge("人" + i, bridge, 1).start();
			} else {
				new PersonCrossBridge("人" + i, bridge, -1).start();
			}
		}
	}

}

class PersonCrossBridge extends Thread {
	private String personName;
	private Bridge bridge;
	private int direction;

	public PersonCrossBridge(String personName, Bridge bridge, int direction) {
		this.personName = personName;
		this.bridge = bridge;
		this.direction = direction;
	}

	public void run() {
		if (direction > 0) {
			bridge.crossFromS2N(personName);
		} else {
			bridge.crossFromN2S(personName);
		}
	}
}

class Bridge {
	public synchronized void crossFromS2N(String person) {
		System.out.print(person + "从南面开始");
		try {
			//模拟过桥
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("---到达北面");
	}

	public synchronized void crossFromN2S(String person) {
		System.out.print(person + "从北面开始");
		try {
			//模拟过桥
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("---到达南面");
	}
}

0 请登录后投票
   发表时间:2011-05-12   最后修改:2011-05-13

lz有点猛了...
http://technoboy.iteye.com/blog/1028828
0 请登录后投票
   发表时间:2011-05-13   最后修改:2011-05-13
谢谢java_user, 如果代码使用inner class,似乎更简练:

class Bridge {
	private static final int TOTAL = 22;
	private int cnt = 0;
    public static void main(String[] args) {  
        Bridge bridge = new Bridge();  
        for (int i = 0; i < TOTAL; i++) {  
            if (i < 10) {  
                new Thread(bridge.new PersonCrossBridge("人" + i,  1) ).start();  
            } else {  
                new Thread(bridge.new PersonCrossBridge("人" + i,  -1)).start();  
            }  
        }  
    }  
    
    public synchronized void crossFromS2N(String person) {  
    	cnt++;
        System.out.print(person + "从南面开始");  
        try {  
            //模拟过桥  
            Thread.sleep(500);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("---到达北面, 共过" +cnt + "人");  
    }  
  
    public synchronized void crossFromN2S(String person) {  
    	cnt++;
        System.out.print(person + "从北面开始");
        try {  
            //模拟过桥  
            Thread.sleep(500);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("---到达南面, 共过" +cnt + "人");  
    }  
    
    class PersonCrossBridge implements Runnable { // extends Thread {  
        private String personName;  
        private int direction;  
      
        public PersonCrossBridge(String personName, int direction) {  
            this.personName = personName;  
            this.direction = direction;  
        }  
      
        public void run() {  
            if (direction > 0) {  
                crossFromS2N(personName);  
            } else {  
                crossFromN2S(personName);  
            }  
        }  
    }  
}  
0 请登录后投票
   发表时间:2011-05-13  
wuyunbin 写道
谢谢java_user, 如果代码使用inner class,似乎更简练:

class Bridge {
	private static final int TOTAL = 22;
	private int cnt = 0;
    public static void main(String[] args) {  
        Bridge bridge = new Bridge();  
        for (int i = 0; i < TOTAL; i++) {  
            if (i < 10) {  
                new Thread(bridge.new PersonCrossBridge("人" + i,  1) ).start();  
            } else {  
                new Thread(bridge.new PersonCrossBridge("人" + i,  -1)).start();  
            }  
        }  
    }  
    
    public synchronized void crossFromS2N(String person) {  
    	cnt++;
        System.out.print(person + "从南面开始");  
        try {  
            //模拟过桥  
            Thread.sleep(500);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("---到达北面, 共过" +cnt + "人");  
    }  
  
    public synchronized void crossFromN2S(String person) {  
    	cnt++;
        System.out.print(person + "从北面开始");
        try {  
            //模拟过桥  
            Thread.sleep(500);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("---到达南面, 共过" +cnt + "人");  
    }  
    
    class PersonCrossBridge implements Runnable { // extends Thread {  
        private String personName;  
        private int direction;  
      
        public PersonCrossBridge(String personName, int direction) {  
            this.personName = personName;  
            this.direction = direction;  
        }  
      
        public void run() {  
            if (direction > 0) {  
                crossFromS2N(personName);  
            } else {  
                crossFromN2S(personName);  
            }  
        }  
    }  
}  

Java是面向对象,代码是简练了,但是你感觉这样设计类合适吗?
0 请登录后投票
   发表时间:2011-05-13  
桥是共享资源是什么意思?


描述有问题啊!是两类人(桥两头)共享还是22个人的共享?不同的理解出来的代码是不一样的
0 请登录后投票
   发表时间:2011-05-13  
如果是22个人的共享,用一下ReentrantLock就行,两类人用ReentrantReadWriteLock就行
0 请登录后投票
   发表时间:2011-05-13  
南北共同过桥应该也是公用一个线程吧!! 只能容纳一个人吧!!
0 请登录后投票
   发表时间:2011-05-13  
楼主这个是类似经典的生产者消费者问题了

如果定义,南边到北边一个人后,紧接着北边到南边一个人,相互交替,才有点意思啊,否则没有突出这个共享桥的概念啊
代码如下:此时南到北,和北到南的人数一致,如果不一致得改代码
public class GapBridge {


public static void main(String[] args) {
Bridge bridge = new Bridge();
SourceToNorth stn = new SourceToNorth(bridge);
new Thread(stn).start();
NorthToSource nts = new NorthToSource(bridge);
new Thread(nts).start();

}
}

class Bridge {
/**
* 定义当direction 为-1时,为南到北,否则为北到南,
* 如果这样定义,则是南边去北边一个,再北边去南边一个,交替
*/
private int direction = -1;

public  synchronized  void sourceToNorth(int count) throws InterruptedException{
//表示已有南去北,等待北去南
if(this.direction == -1){
wait();
}
this.direction = -1;
Thread.sleep(500);
System.out.println("当前线程"+Thread.currentThread().getName()+"第"+count+"个南去北***");
notify();
}

public synchronized void northToSource(int count) throws InterruptedException {
//表示已有北去南,等待南去北
if(this.direction != -1 ){
wait();
}
this.direction = count;
Thread.sleep(500);
System.out.println("当前线程"+Thread.currentThread().getName()+"第"+count+"个北去南---");
notify();
}

}


class SourceToNorth implements Runnable{

private Bridge bridge;

public SourceToNorth(Bridge bridge){
this.bridge = bridge;
}

public void run() {
for(int i=1; i<=10; i++ ){
System.out.println("-------------------------------------"+Thread.currentThread().getName()+ "开始过桥--S-N");
try {
bridge.sourceToNorth(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


}

class NorthToSource implements Runnable {
private Bridge bridge;

public NorthToSource(Bridge bridge){
this.bridge = bridge;
}

public void run() {
for(int i=1; i<=10; i++ ){
System.out.println("-------------------------------------"+Thread.currentThread().getName()+ "开始过桥--N-S");
try {
bridge.northToSource(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}



justinyao 写道
在网上看到这样一道试题,关于多线程的,拿来小练一下
题目:有一个南北向的桥,只能容纳一个人,现桥的两边分别有10人和12人,编制一个多线程序让这些人到达对岸,每个人用一个线程表示,桥为共享资源。在过桥的过程中显示谁在过桥及其走向。

以下是我的代码
package test;

public class MyThread3 extends Thread {

	private String name;
	private String direction;

	public MyThread3(String name, String direction) {
		this.direction = direction;
		this.name = name;
		System.out.println(direction + "方的" + name + "开始过桥...");
	}

	public synchronized void run() {
		try {
			Thread.currentThread().sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(this.direction + "方的" + this.name + "过桥完成!"+"---"+Thread.currentThread().getName());
	}

	public static void main(String[] args) throws InterruptedException {
		MyThread3[] ths = new MyThread3[12];
		int i = 0;
		boolean flag = true;
		while (i <ths.length) {
			if (i < 10)
				ths[i] = new MyThread3("第" + (i+1) + "个人",flag == false ? "北" : "南");
			else
				ths[i] = new MyThread3("第" + (i+1) + "个人", "南");
			ths[i].start();
			ths[i].join();
			ths[i].sleep(1000);
			flag = !flag;
			if (flag == true||i>=10)
				i++;
		}
	}
}


对于synchronized 关键字用法还没完全搞懂,在run中可有可无的

0 请登录后投票
论坛首页 Java企业应用版

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