关于多线程的问题

shenjie1989 2008-12-08 12:40:27
1、哲学家吃饭的问题
2、生产/消费问题
谁能帮我详细的讲解一下,大家对多线程还有其他理解吗?教教我吧,谢谢大家了。
...全文
168 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
jljf_hh 2009-03-31
  • 打赏
  • 举报
回复
学习了。
cuijie_cn 2008-12-10
  • 打赏
  • 举报
回复
哲学家进餐问题是一个多线程运用的经典例子,涉及到线程同步/互斥,临界区访问问题以及一个避免死锁的解决方法。

有五个哲学家绕着圆桌坐,每个哲学家面前有一盘面,两人之间有一支筷子,这样每个哲学家左右各有一支筷子。

哲学家有2个状态,思考或者拿起筷子吃饭。如果哲学家拿到一只筷子,不能吃饭,直到拿到2只才能吃饭,并且一次只能拿起身边的一支筷子。一旦拿起便不会放下筷子直到把饭吃完,此时才把这双筷子放回原处。

如果,很不幸地,每个哲学家拿起他或她左边的筷子,那么就没有人可以吃到饭了。这就会造成死锁了。。这是需要坚决杜绝的,正如操作系统的死锁问题。
中国网管联盟bitsCN.com
代码如下:

import java.util.Random;
public class DiningPhils
{
public static void main(String[] args)
{
int n = 10;
if( n < 1)
{
System.err.println( "DiningPils <# of philosophers>" );
System.exit(-1);
}
DiningPhils self = new DiningPhils();
self.init(n);
}
public int getCount()
{
return n;
}
public void setChopstick( int i, boolean v)
{
chops[ i ] = v;
}
public boolean getChopstick( int i )
{
return chops[i];
}
private void init( final int N)
{
r = new Random();
n = ( N < 0 || N > maxPhils ) ? maxPhils : N;
chops = new boolean[n];
phils = new Philosopher[n];
initPhils();
dumpStatus();
}
private void initPhils()
{
for( int i = 0; i< n; i++ )
{
phils[i] = new Philosopher( this, i );
phils[i].setTimeSlice( generateTimeSlice());
phils[i].setPriority( Thread.NORM_PRIORITY - 1);
/**哲学家进程降低一级,使所有哲学家进程
*全部初始化完毕前不会有哲学家进程抢占主线程*/
}
while( moreToStart() )
{
int i = Math.abs( r.nextInt()) % n;
if( !phils[i].isAlive())
{
System.out.println( " ### Philosopher " +
String.valueOf( i ) + " started.");
phils[i].start();
}
}
System.out.println( "\nPhilosophers Chopsticks"
+ "\n(1 = eating, 0 = thinking) (1 = taken, 0 = free)");
}
public int generateTimeSlice()
{
int ts = Math.abs(r.nextInt()) % (maxEat + 1);
if( ts == 0 )
ts = minEat;
return ts;
}
public void dumpStatus()
{
for( int i = 0; i < n; i++)
System.out.print(phils[i].getEat() ? 1 : 0);
for( int i = n; i < maxPhils + 4; i++ )
System.out.print(" ");
for( int i = 0; i < n; i++)
System.out.print(chops[i]? 1:0);
System.out.println();
}
private boolean moreToStart()
{
for( int i = 0; i < phils.length; i++ )
{
if( !phils[i].isAlive())
return true;
}
return false;
}
private int n;
private Philosopher[] phils;
private boolean[] chops;
private Random r;
private static final int maxPhils = 24; //最多哲学家数
private static final int maxEat = 4; //最多进餐时间
private static final int minEat = 1; //最少进餐时间
}
class Philosopher extends Thread
{
public Philosopher( DiningPhils HOST , int i )
{
host = HOST;
index = i;
}
public void setTimeSlice( int TS )
{
ts = TS;
}
public void setLeftChopstick( boolean flag )
{
host.setChopstick(index, flag);
}
public void setRightChopstick( boolean flag )
{
host.setChopstick((index + 1)% host.getCount() , flag);
}
private void releaseChopsticks()
{
setLeftChopstick(false);
setRightChopstick(false);
}
public boolean chopsticksFree()
{
return !host.getChopstick(index) &&
!host.getChopstick((index+1)%host.getCount());
}
public void run()
{
while(true)
{
grabChopsticks();
eat();
think();
}
}
private synchronized void grabChopsticks() /**临界区函数,确保哲学家在没有筷子或筷子不够时思考,满足条件后才就餐*/
{
while( !chopsticksFree())
{
try
{
wait();
}
catch( InterruptedException e){}
}
takeChopsticks();
notifyAll();
}
private void takeChopsticks()
{
setLeftChopstick( true );
setRightChopstick( true );
setEat(true);
host.dumpStatus();
}
private void eat()
{
pause();
setEat( false );
releaseChopsticks();
}
private void think()
{
pause();
}
private void pause()
{
setTimeSlice( host.generateTimeSlice());
try
{
sleep(ts*1000);
}
catch( InterruptedException e){}
}
private void setEat(boolean v)
{
isEating = v;
}
public boolean getEat()
{
return isEating;
}
private DiningPhils host;
private boolean isEating;
private int index;
private int ts;
}
lc7cl 2008-12-10
  • 打赏
  • 举报
回复
楼主要干嘛啊!
redchenhong 2008-12-10
  • 打赏
  • 举报
回复
具体概念不是很记得,只有运用时才知道如何玩于鼓掌之中。……呵呵。没帮上忙非常不好意思。不过我来帮你顶帖。希望有更多高手过来帮你解释~
njzdl 2008-12-10
  • 打赏
  • 举报
回复
想要理解什么?
cuijie_cn 2008-12-10
  • 打赏
  • 举报
回复
 生产-消费者模型是多线程编程中的基本模型也是运用最多的模型,而它的原理就是一个线程向缓冲池中扔东西,另一个线程从缓冲池中把东西拿走.所以在这个模型中缓冲池是一个核心,它是生产-消费者之间的桥梁并且能进行一些控制.池满了则生产者必须等待,池空了则消费者必须等待.这里的关键就是缓冲池必须是固定大小不能随意扩充,因为程序一瞬间就能把堆耗尽.就是好比我们去蛋糕店买蛋糕,柜台和货架就是缓冲池糕点师是不能无限制的做蛋糕.所以缓冲池的最大,最小值(不一定为0)就是临界条件.而在我前面的文章中提到了使用Event_Trigger(实际上Event_Trigger就是Semaphore,只不过我自己实现了一个Semaphore)来控制临界条件,而不是使用双重检测这种东西(当然不是说双重检测无用,只是应用面很小).我自己实现的锁Unique中使用了它(但没有用Event_Trigger来控制临界条件,在本文中将使用.).我喜欢用Queue来做缓冲池的载体,因为在某些应用中会要求先后顺序(FIFO).

public class Info_Queue<_Info>
...{
    Queue<_Info> _queue;
    Event_Trigger _produce;
    Event_Trigger _consume;
    Unique _locker = new Unique();
    public Info_Queue(int size)
    ...{
      this._queue = new Queue<_Info>(size);
      this._produce = new Event_Trigger(size);
      this._consume = new Event_Trigger();
    }
    public void Push(_Info item)
    ...{
      this._produce.Wait();
      this._locker.Lock();
      this._queue.Enqueue(item);
      this._locker.UnLock();
      this._consume.Post();
    }
    public _Info Pop()
    ...{
      this._consume.Wait();
      _Info item = default(_Info);
      this._locker.Lock();
      item = this._queue.Dequeue();
      this._locker.UnLock();
      this._produce.Post();
      return item;
    }
    public int Count()
    ...{
      return this._queue.Count;
    }
    public void Clear()
    ...{
      this._queue.Clear();
      this._locker.Close();
      this._produce.Close();
      this._consume.Close();
    }
}

tiyuzhongxin789 2008-12-08
  • 打赏
  • 举报
回复
具体概念不是很记得,只有运用时才知道如何玩于鼓掌之中。……呵呵。没帮上忙非常不好意思。不过我来帮你顶帖。希望有更多高手过来帮你解释~
HuanxueOrSeaty 2008-12-08
  • 打赏
  • 举报
回复
学习
JackyNone 2008-12-08
  • 打赏
  • 举报
回复
楼上的楼上的楼上很搞笑
metruetian 2008-12-08
  • 打赏
  • 举报
回复
具体概念不是很记得,只有运用时才知道如何玩于鼓掌之中。……呵呵。没帮上忙非常不好意思。不过我来帮你顶帖。希望有更多高手过来帮你解释~
wm920 2008-12-08
  • 打赏
  • 举报
回复


去看 这个资料吧;

http://www.intel.com/cd/ids/developer/apac/zho/242317.htm?page=4
guogaocheng 2008-12-08
  • 打赏
  • 举报
回复
class ProduceInteger extends Thread
{
private HoldInteger sharedObject;
public ProduceInteger(HoldInteger shared)
{
sharedObject=shared;
}

public void run()
{
for(int count=1;count <8;count )
{
try
{
Thread.sleep(((int)Math.random()*3000));
sharedObject.setSharedInt(count);
}
catch(InterruptedException exception)
{
}
System.out.println( "Producer # " count "done producing, put: " count);
}
}
}

class ConsumeInteger extends Thread
{
private HoldInteger sharedObject;
public ConsumeInteger(HoldInteger shared)
{
sharedObject=shared;
}

public void run()
{
int value=0;
for(int i=1;i <8;i )
{
try
{
Thread.sleep(((int)Math.random()*3000));
value=sharedObject.getSharedInt();
}
catch(InterruptedException exception)
{
}
System.out.println( "Consumer # " i "done consuming, got: " value);
}
}

}

class HoldInteger
{
private int sharedInt=-1;
boolean available=false;

public synchronized void setSharedInt(int value)
{
while(available==true)
{
try
{
System.out.println( "Producer tries to wite,Buffer is full.Wait ");
wait();
}
catch(InterruptedException e)
{
}
}
sharedInt=value;
available=true;
notifyAll();
}
public synchronized int getSharedInt()
{
while(available==false)
{
try
{
System.out.println( "Consumer tries to read,Buffer is empty.Wait ");
wait();
}
catch(InterruptedException e)
{
}
}
available=false;
notifyAll();
System.out.println( "实验 ");
return sharedInt;
}
}

public class ProdAndCons {

public static void main(String[] args) {
HoldInteger sharedObject=new HoldInteger();
ProduceInteger producer=new ProduceInteger(sharedObject);
ConsumeInteger consumer=new ConsumeInteger(sharedObject);
producer.start();
consumer.start();

}

}
jefflovejava 2008-12-08
  • 打赏
  • 举报
回复
这些都是有关于,多线程中,资源共享和防止死锁等问题,到时候你应该怎么去控制各个线程的并发,这个需要具体情况具体分析
acRush7 2008-12-08
  • 打赏
  • 举报
回复
这应该都是学习操作系统时候的例子,我觉得应该去看下操作系统的书看下
西瓜 2008-12-08
  • 打赏
  • 举报
回复

public class Sample09 {

/**
* @param args
*/
public static void main(String[] args) {
// ExecutorService es = Executors.newFixedThreadPool(3);
// ExecutorService es = Executors.newSingleThreadExecutor();
ExecutorService es = Executors.newCachedThreadPool();

for (int i = 0; i < 1000; i++) {
Task t = new Task();
es.submit(t);
}

System.out.println("加载任务完成");
es.shutdown();
System.out.println("main is over");
}
}

class Task implements Runnable {
private String name = "";

private static int num = 1;

private static int step = 0;

private long sleepTime = 200;

public Task(String name, long sleepTime) {
this.name = name;
this.sleepTime = sleepTime;
}

public Task() {
this("task-" + num, 200);
num++;
}

public void run() {
int num = 1;
int all = new Random().nextInt(20) + 1;
System.out.println("\n==========" + Thread.currentThread().getName()
+ "开始执行" + name + "任务(该任务有" + all + "步)" + "==========");
step = 0;
while (num <= all) {
System.out.print("执行任务" + name + "第" + num++ + "步 ");
step++;
if (step % 6 == 0) {
System.out.println();
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("\n==========" + Thread.currentThread().getName()
+ "执行完毕==========");
step = 0;
}
}
西瓜 2008-12-08
  • 打赏
  • 举报
回复

public class Sample08 extends Thread {
private Object o1 = null;

private Object o2 = null;

public Sample08(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}

public void run() {
synchronized (o1) {
System.out.println(Thread.currentThread().getName() + "锁住对象" + o1);

try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}

synchronized (o2) {
System.out.println(Thread.currentThread().getName() + "锁住对象" + o2);
}
System.out.println(Thread.currentThread().getName() + "释放对象" + o2);
}
System.out.println(Thread.currentThread().getName() + "释放对象" + o1);
}

/**
* @param args
*/
public static void main(String[] args) {
String str1 = "str1";
String str2 = "str2";
String str3 = "str3";

Sample08 t1 = new Sample08(str1, str2);
Sample08 t2 = new Sample08(str2, str3);
Sample08 t3 = new Sample08(str3, str1);

t1.start();
t2.start();
t3.start();
}

}

西瓜 2008-12-08
  • 打赏
  • 举报
回复

public class Sample07 {

/**
* @param args
*/
public static void main(String[] args) {
Warehouse wh = new Warehouse();
Product p1 = new Product(wh);
Product p2 = new Product(wh);
Consumer c = new Consumer(wh);

c.start();

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

p1.start();
p2.start();
}

}

class Product extends Thread {
private Warehouse wh = null;

public Product(Warehouse wh) {
this.wh = wh;
}

public void run() {
int num = 1;

while (num < 21) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
wh.push(num++);
}
}
}

class Consumer extends Thread {
private Warehouse wh = null;

public Consumer(Warehouse wh) {
this.wh = wh;
}

public void run() {
while (true) {

try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (wh.pop() == 20) {
break;
}
}
}
}

class Warehouse {
private int num = 0;

private boolean isFull = false;

public synchronized void push(int num) {
if (!isFull) {
this.num = num;
System.out.println("生产者" + Thread.currentThread().getName() + "放入--->" + num);
isFull = true;
notify();
}

if (isFull) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public synchronized int pop() {
if (isFull) {
System.out.println("消费者获得--->" + num);
isFull = false;
notifyAll();
return num;
}

if (!isFull) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return -1;
}
}

ar7043 2008-12-08
  • 打赏
  • 举报
回复
楼主百度一下应该很多的~java的不知道有没~但以前linux老师让用c写过一个。操作系统书上应该都有
dengfeiling 2008-12-08
  • 打赏
  • 举报
回复
哲学家吃饭是为了生存
生产/消费是为了国家经济发展
^_^
RJCHEN1985 2008-12-08
  • 打赏
  • 举报
回复
想讲解什么呢?

62,614

社区成员

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

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