Java 代码中发生的死锁
下面是我对并发问题的实现:Java 代码中发生的死锁,java,multithreading,deadlock,Java,Multithreading,Deadlock,下面是我对并发问题的实现: 5个哲学家,每个哲学家延伸线程: 问题是每次程序在死锁内完成时。我尝试了不同的解决方案,但没有人解决这个问题。 也许有人能帮我。 这是我的节目: import java.util.concurrent.ThreadLocalRandom; class Fork { public static final char FORK = '|'; public static final char NO_FORK = ' '; int id;
5个哲学家,每个哲学家延伸线程:
问题是每次程序在死锁内完成时。我尝试了不同的解决方案,但没有人解决这个问题。
也许有人能帮我。
这是我的节目:
import java.util.concurrent.ThreadLocalRandom;
class Fork {
public static final char FORK = '|';
public static final char NO_FORK = ' ';
int id;
public Fork(final int id) {
this.id = id;
}
}
class Philosopher extends Thread {
public static final char PHIL_THINKING = '-';
public static final char PHIL_LEFT_FORK = '=';
public static final char PHIL_EATING = 'o';
private final int id;
public Philosopher(final int id) {
this.id = id;
}
@Override
public void run() {
final int tableOffset = 4 * id;
final Object leftLock = S5Philosophers.listOfLocks[id];
final Object rightLock = S5Philosophers.listOfLocks[(id + 1)
% S5Philosophers.NUM_PHILOSOPHERS];
final int table__farL = tableOffset + 0;
final int table__left = tableOffset + 1;
final int table_philo = tableOffset + 2;
final int table_right = tableOffset + 3;
final int table__farR = (tableOffset + 4)
% (4 * S5Philosophers.NUM_PHILOSOPHERS);
while (!isInterrupted()) {
try {
Thread.sleep(S5Philosophers.UNIT_OF_TIME
* (ThreadLocalRandom.current().nextLong(6)));
} catch (final InterruptedException e) {
break;
}
// Try to get the chopstick on the left
synchronized (leftLock) {
synchronized (S5Philosophers.class) {
S5Philosophers.dinerTable[table__farL] = Fork.NO_FORK;
S5Philosophers.dinerTable[table__left] = Fork.FORK;
S5Philosophers.dinerTable[table_philo] = PHIL_LEFT_FORK;
}
try {
sleep(S5Philosophers.UNIT_OF_TIME * 1);
} catch (final InterruptedException e) {
break;
}
// Try to get the chopstick on the right
synchronized (rightLock) {
synchronized (S5Philosophers.class) {
S5Philosophers.dinerTable[table_philo] = PHIL_EATING;
S5Philosophers.dinerTable[table_right] = Fork.FORK;
S5Philosophers.dinerTable[table__farR] = Fork.NO_FORK;
//notify();
}
try {
sleep(S5Philosophers.UNIT_OF_TIME * 1);
} catch (final InterruptedException e) {
break;
}
// Release fork
synchronized (S5Philosophers.class) {
S5Philosophers.dinerTable[table__farL] = Fork.FORK;
S5Philosophers.dinerTable[table__left] = Fork.NO_FORK;
S5Philosophers.dinerTable[table_philo] = PHIL_THINKING;
S5Philosophers.dinerTable[table_right] = Fork.NO_FORK;
S5Philosophers.dinerTable[table__farR] = Fork.FORK;
//notify();
}
}
}
}
}
}
public class S5Philosophers {
public static final int NUM_PHILOSOPHERS = 5;
public static final int UNIT_OF_TIME = 50;
public static final Fork[] listOfLocks = new Fork[NUM_PHILOSOPHERS];
public static char[] dinerTable = null;
static {
for (int i = 0; i < NUM_PHILOSOPHERS; i++)
listOfLocks[i] = new Fork(i);
}
public static void main(final String[] a) {
final char[] lockedDiner = new char[4 * NUM_PHILOSOPHERS];
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
lockedDiner[4 * i + 0] = Fork.NO_FORK;
lockedDiner[4 * i + 1] = Fork.FORK;
lockedDiner[4 * i + 2] = Philosopher.PHIL_LEFT_FORK;
lockedDiner[4 * i + 3] = Fork.NO_FORK;
}
final String lockedString = new String(lockedDiner);
// safe publication of the initial representation
synchronized (S5Philosophers.class) {
dinerTable = new char[4 * NUM_PHILOSOPHERS];
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
dinerTable[4 * i + 0] = Fork.FORK;
dinerTable[4 * i + 1] = Fork.NO_FORK;
dinerTable[4 * i + 2] = Philosopher.PHIL_THINKING;
dinerTable[4 * i + 3] = Fork.NO_FORK;
}
}
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
final Thread t = new Philosopher(i);
// uses this solution to allow terminating the application even if
// there is a deadlock
t.setDaemon(true);
t.start();
}
System.out.println("The diner table:");
long step = 0;
while (true) {
step++;
String curTableString = null;
synchronized (S5Philosophers.class) {
curTableString = new String(dinerTable);
}
System.out.println(curTableString + " " + step);
if (lockedString.equals(curTableString))
break;
try {
Thread.sleep(UNIT_OF_TIME);
} catch (final InterruptedException e) {
System.out.println("Interrupted.");
}
}
System.out.println("The diner is locked.");
}
}
import java.util.concurrent.ThreadLocalRandom;
类叉{
公共静态final char FORK='|';
公共静态最终字符NO_FORK='';
int-id;
公共分叉(最终int id){
this.id=id;
}
}
类扩展线程{
公共静态最终字符PHIL_THINKING='-';
公共静态最终字符PHIL_LEFT_FORK='=';
公共静态最终字符PHIL_EATING='o';
私有最终int id;
公共哲学家(最终整数id){
this.id=id;
}
@凌驾
公开募捐{
最终int tableOffset=4*id;
final Object leftLock=s5philosphers.listoflock[id];
最终对象rightLock=S5Philosophers.ListoFlock[(id+1)
%S5Philosophers.NUM_哲学家];
最终int table_uuuFARL=表格偏移量+0;
最终整型表格左=表格偏移量+1;
最终int table_philo=表格偏移量+2;
最终int表格右=表格偏移量+3;
最终整数表_uufarr=(表偏移量+4)
%(4*S5哲学家、无数哲学家);
而(!isInterrupted()){
试一试{
线程.睡眠(S5Philosophers.UNIT OF the_TIME
*(ThreadLocalRandom.current().nextLong(6));
}捕获(最终中断异常e){
打破
}
//试着把筷子放在左边
已同步(左锁){
已同步(S5Philosophers.class){
S5Philosophers.dinerTable[餐桌]=Fork.NO\u Fork;
S5Philosophers.dinerTable[桌子左]=Fork.Fork;
S5Philosophers.dinerTable[table_philo]=PHIL_LEFT_FORK;
}
试一试{
睡眠(S5Philosophers.UNIT OF_TIME*1);
}捕获(最终中断异常e){
打破
}
//试着把筷子放在右边
已同步(右锁){
已同步(S5Philosophers.class){
S5Philosophers.dinerTable[table_philo]=PHIL_EATING;
S5Philosophers.dinerTable[餐桌右]=Fork.Fork;
S5Philosophers.dinerTable[餐桌]=Fork.NO\u Fork;
//通知();
}
试一试{
睡眠(S5Philosophers.UNIT OF_TIME*1);
}捕获(最终中断异常e){
打破
}
//释放叉
已同步(S5Philosophers.class){
S5Philosophers.dinerTable[餐桌]=Fork.Fork;
S5Philosophers.dinerTable[桌子左]=Fork.NO\u Fork;
S5Philosophers.dinerTable[table_philo]=Philu THINKING;
S5Philosophers.dinerTable[餐桌右]=Fork.NO\u Fork;
S5Philosophers.dinerTable[餐桌]=Fork.Fork;
//通知();
}
}
}
}
}
}
公共类S5哲学家{
公共静态最终整数=5;
公共静态最终整数单位,单位为时间=50;
publicstaticfinalfork[]listoflock=newfork[NUM_];
public static char[]dinerTable=null;
静止的{
for(int i=0;i
您的策略是先锁定左边的叉子(或筷子?似乎您无法决定…)。但每个哲学家对“左叉子”都有不同的概念。应该很容易想象到,有可能进入这种情况
class Fork {
public static final char FORK = '|';
public static final char NO_FORK = ' ';
private int id;
private Lock lock = new ReentrantLock();
public Fork(final int id) {
this.id = id;
}
public boolean isHeld() {
return lock.isLocked();
}
// returns true if successfully grabbed!
public synchronized boolean tryToGrab() {
return lock.tryLock();
}
public void letGo() {
lock.unlock();
}
}
class Philosopher implements Runnable { ... }
...
Thread t = new Thread(new Philosopher());
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
Lock[] listOfLocks = new Lock[NUM_PHILOSOPHERS];
for (int i=0 ; i<listOfLocks.length ; i++) {
listOfLocks[i] = new ReentrantLock();
}
interface Strategy {
//returns after locking both the leftLock and the rightLock
public void grabSticks(Lock leftLock, Lock rightLock);
}
class Philosopher implements Runnable {
private final Strategy strategy;
public Philosopher(Strategy strategy) {
this.strategy = strategy;
}
@Override
public void run() {
...
while (...) {
think();
strategy.grabSticks(leftLock, rightLock);
eat();
leftLock.unlock();
rightLock.unlock();
}
}
}