我正在尝试编写一段代码,其中多个线程调用共享对象上的方法来递增/递减/打印存储在其中的计数器。我还希望这些数字介于0和8之间。也就是说,输出可能如下所示:0123234567654566677877666655。
有没有人能看看我做了些什么,并给我一些建议,看看我是否走对了路:
我的共享对象:
public class SyncObj{
private int i;
public synchronized void inc(){
if(i<8)
i++;
}
public synchronized void dec(){
if(i > 0)
i--;
}
public synchronized void print(){
System.out.print(i);
}
}为了防止打印时出现资源匮乏,并确保打印每个inc/dec,我可以使用一个名为hasPrinted的私有变量并重写该类,如下所示:
public class SyncObj{
private int i;
//Changed Boolean to boolean as Keith Randall pointed out
private boolean hasPrinted = false;
public synchronized void inc(){
if(i<8 && hasPrinted){
i++;
hasPrinted = false;
}
}
public synchronized void dec(){
if(i > 0 && hasPrinted){
i--;
hasPrinted = false;
}
}
public synchronized void print(){
System.out.print(i);
hasPrinted = true;
}
}有人可以检查上面的代码片段并检查它的陷阱和陷阱吗?
谢谢
发布于 2012-04-07 02:08:20
您应该习惯于使用队列进行打印。
public class SyncObj {
private volatile int i;
private BlockingQueue<Integer> q = new LinkedBlockingQueue<Integer>();
public synchronized void inc() {
if (i < 8) {
i++;
q.add(i);
}
}
public synchronized void dec() {
if (i > 0) {
i--;
q.add(i);
}
}
public void print() {
for (Integer i = q.poll(); i != null; i = q.poll()) {
System.out.print(i);
}
}
private static volatile boolean stop = false;
public static void main(String[] args) throws InterruptedException {
final SyncObj o = new SyncObj();
new Thread(new Runnable() {
@Override
public void run() {
while (!stop) {
o.inc();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (!stop) {
o.dec();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (!stop) {
o.print();
}
}
}).start();
Thread.currentThread().sleep(1000);
stop = true;
}
}我的输出如下所示:
1012345678765432101234567876543210123456787654321012345678765432101234567876543210123456787654321012345678
发布于 2012-04-07 00:12:59
Boolean -> boolean,用对象代替原始类型是没有意义的。
您的第一个代码很好。您的第二个代码不能解决防止饥饿或确保打印每个inc/dec的需求。为什么不让inc/dec自己打印值呢?
https://stackoverflow.com/questions/10046044
复制相似问题