创建一个 runnable,并使用您在上述 runnable 中定义的 setter 和 getter。
public class MyRunnable implements Runnable{
private volatile String myString;
public String setString(String value){this.myString = value;}
public String getString(){
return myString;
}
public void run(){}
}
注意volatile
关键字在这里使用。volatile 关键字确保如果此字符串在一个线程中发生更改,则所有线程都会看到更改。相反,如果我确保对 String 对象的唯一访问是通过同步上下文,那么 volatile 关键字就不是必需的。
为了证明我的观点,上面的代码和下面的代码都是线程安全的,但不同的是,在下面的示例中,没有 2 个线程可以setString
同时进入getString
。
public class MyRunnable implements Runnable{
private String myString;
public synchronized String setString(String value){this.myString = value;}
public synchronized String getString(){
return myString;
}
public void run(){}
}
一个线程实际上只是在执行一个可运行的。你可以这样使用它:
MyRunnable runnable = new MyRunnable();
Thread myThread = new Thread(runnable);
myThread.start();
String myString = runnable.getString();
对原语使用原子值很好,但是如果您想共享更复杂的对象,则必须阅读有关线程和同步的内容。
例如:
public class Stats{
int iterations;
long runtime;
public Stats(){
iterations = 0;
runtime=0;
}
public synchronized void setIterations(int value){this.iterations = value;}
public synchronized void setRuntime(long milliseconds){
this.runtime = milliseconds;
}
public synchronized int getIterations(){
return iterations;
}
public synchronized long getRuntime(){return runtime;}
}
public class StatRunnable implements Runnable{
Stats stats;
boolean active;
public StatRunnable(){
this.active=true;
}
public Stats getStats(){
return stats;
}
long calculateRuntime(){return 0L;}
public void run(){
while(active){
//i'm synchronizing with stats to ensure no other thread alters values
//simultaneously.
synchronized(stats){
stats.setIterations(stats.getIterations()+1);
stats.setRuntime(calculateRuntime());
}
}
}
}
synchronized
此代码显示了通过关键字与非原始对象同步的示例。在方法定义中使用 synchronized 关键字会锁定使用自身作为同步对象的类。
最后一点,同步关键字不仅仅用于方法定义。您可以使用它来同步方法中的实例,就像我run
在StatRunnable
.