锁定老帖子 主题:java 多线程小练
精华帖 (0) :: 良好帖 (1) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-05-13
牛人好多,我看到线程就晕倒。
|
|
返回顶楼 | |
发表时间:2011-05-13
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中可有可无的 额 。。。 lz这段代码貌似和线程锁没什么关系嘛。。。。就一个flag标签控制南北两个方向交叉过河。。。。。 synchronized 关键字用来声明锁。 synchronized有两种用法: 一种:synchronized 放在方法前。用来加锁当前对象。相当于method{synchronized(this){}} 第二种:synchronized语句块。 synchronized(source){} 表示在执行synchronized语句块中的语句时,需要等待source的资源锁。source 一般可以为this 、Xxx.class。 小白的理解, 期待大牛斧正!!!! ![]() ![]() ![]() |
|
返回顶楼 | |
发表时间:2011-05-13
既然桥是公共资源,我想synchronized就作用到桥上比较好点。
class GapBridge implements Runnable { //桥是公共资源,而且是单向通道因此需要被锁定 private Object obj; //方向判断 private boolean flag; public GapBridge (Object obj, boolean flag){ this.obj = obj; this.flag = flag; } @Override public void run() { synchronized (obj) { try { Thread.sleep(700); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(flag){ System.out.println("第" + Thread.currentThread().getName() + "从北向南过桥!"); }else{ System.out.println("第" + Thread.currentThread().getName() + "从南向北过桥!"); } } } } |
|
返回顶楼 | |
发表时间:2011-05-13
LZ第一个代码比较符合你题目。。。。。。呵呵
|
|
返回顶楼 | |
发表时间:2011-05-13
额,受教了
|
|
返回顶楼 | |
发表时间:2011-05-14
最后修改:2011-05-14
用线程池写了代码,也实现了其功能,但老觉得没把线程池的作用充分发挥出来,请教各位
public class ThreadTestOne implements Runnable { private ExecutorService pool; private int poolSize; private int NorthToSouth; private int SouthToNorth; public ThreadTestOne(int NorthToSouth, int SouthToNorth) { this.NorthToSouth = NorthToSouth; this.SouthToNorth = SouthToNorth; this.poolSize = Math.max(NorthToSouth, SouthToNorth); pool = Executors.newFixedThreadPool(poolSize); } public synchronized void run() { boolean flag = true; for (int i = 0; i < poolSize; i++) { if (i < Math.min(NorthToSouth, SouthToNorth)) { pool.execute(new Handler("第" + (i + 1) + "个人", flag == false ? "北" : "南")); } else { pool.execute(new Handler("第" + (i + 1) + "个人", "南")); } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } flag = !flag; } pool.shutdown(); } class Handler implements Runnable { private String name; private String direction; public Handler(String name, String direction) { this.direction = direction; this.name = name; System.out.println(direction + "方的" + name + "开始过桥..."); } public void run() { System.out.println(this.direction + "方的" + this.name + "过桥完成!" + "---" + Thread.currentThread().getName()); } } public static void main(String[] args) throws InterruptedException { //test ThreadTestOne threadTestOne = new ThreadTestOne(12, 10); threadTestOne.run(); } } |
|
返回顶楼 | |
发表时间:2011-05-14
最后修改:2011-05-14
freish 写道 如果是22个人的共享,用一下ReentrantLock就行,两类人用ReentrantReadWriteLock就行
既然JDK1.5有更安全的Thread使用方式,也是推荐的使用方式,我们就应多使用这个特性来编写多线程程序,以下是我试写的,分享下,和大家共同进步,希望有更好的建议: package dong.concurrency; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Bridge { final ReentrantLock lock = new ReentrantLock(); final Condition codition = lock.newCondition(); volatile boolean isFree = true; ExecutorService exec = Executors.newFixedThreadPool(22); public Bridge() { } private void generatePerson() { for (int i = 1; i <= 22; i++) { if (i <= 10) exec.execute(new Person(this, Direction.values()[0], i)); else exec.execute(new Person(this, Direction.values()[1], i)); } } public static void main(String[] args) { Bridge bridge = new Bridge(); bridge.generatePerson(); bridge.exec.shutdown(); } } enum Direction { SOUTHTONORTH("South---->North"), NORTHTOSOUTH("North--->South"); private String desc; Direction(String dirc) { desc = dirc; } @Override public String toString() { return desc; } } class Person implements Runnable { private Bridge bridge; private Direction direction; private final int id; private static Random rand = new Random(); public Person(Bridge bridge, Direction direction, int id) { this.bridge = bridge; this.direction = direction; this.id = id; } @Override public String toString() { return "Person " + id + " crossed bridge from " + direction.toString(); } @Override public void run() { crossBridge(); } private void crossBridge() { bridge.lock.lock(); try { try { while (!bridge.isFree) bridge.codition.await(); System.out.println(toString()); bridge.isFree = true; bridge.codition.signalAll(); TimeUnit.MILLISECONDS.sleep(rand.nextInt(500)); } catch (Exception e) { e.printStackTrace(); } } finally { bridge.lock.unlock(); } } } |
|
返回顶楼 | |
发表时间:2011-05-14
panpan123mail 写道 用线程池写了代码,也实现了其功能,但老觉得没把线程池的作用充分发挥出来,请教各位
public class ThreadTestOne implements Runnable { private ExecutorService pool; private int poolSize; private int NorthToSouth; private int SouthToNorth; public ThreadTestOne(int NorthToSouth, int SouthToNorth) { this.NorthToSouth = NorthToSouth; this.SouthToNorth = SouthToNorth; this.poolSize = Math.max(NorthToSouth, SouthToNorth); pool = Executors.newFixedThreadPool(poolSize); } public synchronized void run() { boolean flag = true; for (int i = 0; i < poolSize; i++) { if (i < Math.min(NorthToSouth, SouthToNorth)) { pool.execute(new Handler("第" + (i + 1) + "个人", flag == false ? "北" : "南")); } else { pool.execute(new Handler("第" + (i + 1) + "个人", "南")); } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } flag = !flag; } pool.shutdown(); } class Handler implements Runnable { private String name; private String direction; public Handler(String name, String direction) { this.direction = direction; this.name = name; System.out.println(direction + "方的" + name + "开始过桥..."); } public void run() { System.out.println(this.direction + "方的" + this.name + "过桥完成!" + "---" + Thread.currentThread().getName()); } } public static void main(String[] args) throws InterruptedException { //test ThreadTestOne threadTestOne = new ThreadTestOne(12, 10); threadTestOne.run(); } } 有这感觉,线程池用在大量线程系统,和更复杂的线程交互可能更有用,简单的线程交互用传统的方式会较简单,不过好像代码量也差不多。 |
|
返回顶楼 | |
发表时间:2011-05-14
import threading import time from collections import deque class Person(threading.Thread): def __init__(self, id, msg): threading.Thread.__init__(self) self.id = id self.msg = msg def run(self): cross(self) def cross(self): print(str(self.id) + "\t" + self.msg) class PersonPool(threading.Thread): canCross = threading.RLock() def __init__(self): threading.Thread.__init__(self) self.persons = deque([]) self.shutdown = False def add(self, person): self.persons.append(person) def stop(self): self.shutdown = True def run(self): self.waitForPerson() def waitForPerson(self): while self.shutdown == False: PersonPool.canCross.acquire() while len(self.persons) != 0: person = self.persons.popleft() person.cross() time.sleep(1) PersonPool.canCross.release() if __name__ == "__main__": nsPool = PersonPool() snPool = PersonPool() snPool.start() nsPool.start() for i in xrange(0, 10): snPool.add(Person(i, "From North To South")) for j in xrange(0, 12): snPool.add(Person(j, "From South To North")) |
|
返回顶楼 | |
发表时间:2011-05-15
共享资源通常就是要锁定的对象,每个人启一个线程,用wait/notify协作,桥作为互斥对象,就是要被synchronized的锁对象
|
|
返回顶楼 | |