Java同步和线程 [英] Java Synchronized and Threads

查看:121
本文介绍了Java同步和线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了与Synchronized行为不符的问题,我也尝试使用volatile关键字:

I'm having issues with Synchronized not behaving the way i expect, i tried using volatile keyword also:

共享对象:

public class ThreadValue {

    private String caller;
    private String value;

    public ThreadValue( String caller, String value ) {
        this.value = value;
        this.caller = caller;
    }

    public synchronized String getValue() {
        return this.caller + "     "  + this.value;
    }
    public synchronized void setValue( String caller, String value ) {
        this.caller = caller;
        this.value = value;
    }
}

线程1:

class CongoThread implements Runnable {
    private ThreadValue v;
    public CongoThread(ThreadValue v) {
        this.v = v;
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            v.setValue( "congo", "cool" );
            v.getValue();
        }
    }
}

线程2:

class CongoThread implements Runnable {
    private ThreadValue v;
    public CongoThread(ThreadValue v) {
    this.v = v;

    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            v.setValue( "congo", "lame" );
            v.getValue();
        }
    }
}

呼叫班:

class TwoThreadsTest {
    public static void main (String args[]) {

        ThreadValue v = new ThreadValue("", "");
        Thread congo = new Thread( new CongoThread( v ) );
        Thread libya = new Thread( new LibyaThread( v ) );

        libya.start();
        congo.start();
    }
}

有时我会得到"In Libya Thread congo cool" 这永远都不会发生.我只希望:
"In Libya Thread libya awesome"
"In Congo Thread congo cool"

Occasionally i get "In Libya Thread congo cool" which should never happen. I expect only:
"In Libya Thread libya awesome"
"In Congo Thread congo cool"

我不希望他们混在一起.

I dont expect them to be mixed.

推荐答案

发生了以下情况:

  1. 线程1设置值
  2. 线程2设置值
  3. 线程1读取线程2设置的值.

要解决此问题,您需要具有1个锁定对象,以保护两个线程的get/set函数调用.最好的方法是制作一个同时执行set和get的额外同步方法.但是有时候这是不希望的.在那种情况下,给两个线程一个锁对象.这只是一个普通的对象.然后在同步块中使用它们.

In order to fix this you need to have 1 lock object that guards the get/set functions call for both threads. The best way to do this, is to make an extra synchronized method that does both the set and the get. However sometimes that isn't desirable. In that case give both threads a lock object. Which is just a plain object. Which they then use in a synchronized block.

每个线程的实现如下所示,请注意,它们需要具有完全相同的对象!

Implementation of each thread would like like the following, note that they need to have precisely the same object!

Object lockObject = new Object();
Thread t1 = new CongroThread(v, lockObject);
Thread t2 = new LibyaThread(v, lockObject);

...

class CongoThread implements Runnable {
    private ThreadValue v;
    private Object lockObject;

    public CongoThread(ThreadValue v, Object lockObject) {
    this.v = v;
    this.lockObject = lockObject,
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            synchronized(lockObject)
            {
                v.setValue( "congo", "lame" );
                v.getValue();
            }
        }
    }
}

这篇关于Java同步和线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆