Reputation:
I think I have a synchronization problem...It may be too basic..Please help..
I have a thread the run method of which is below
public void run()
{
while(true)
{
try {
for (int i = 0; i < 100; i++) {
buf.append(hello + (myint++));
}
buf.append("\n");
adapter.setData(buf.toString());
buf = null;
buf = new StringBuffer();
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(TestThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
I am creating new string data in each run and passing it to the adapter class setData method..
In the adapter class my setData is like this..
public boolean setData(String sb){
str = sb;
if(str != null && !str.equalsIgnoreCase("")){
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("inside run.....");
System.out.println("str length:- "+str.length());
//do sth after this..
}
}
But once in a while I get null pointer exception at the line str.length()...I get this even when I try to create a new string with the buf.toString() in the first run method..
What am I doing wrong??
Thanks in advance..
Upvotes: 0
Views: 1830
Reputation: 163
Try using get and set methods for the "str" which will be synchronized using a syncronization object:
private static Object syncObject = new Object();
public String getStr(){
synchronized (syncObject){
return str;
}
}
public void setStr(String value){
synchronized (syncObject){
str = value;
}
}
And insted:
str=sb;
try:
setStr(sb);
and insted:
System.out.println("str length:- "+str.length());
try:System.out.println("str length:- "+getStr().length());
Upvotes: 0
Reputation: 346300
What you are doing wrong is this: the buf
and str
are apparently both instance or static fields accessed unsynchronized by multiple threads.
It almost looks like you aren't aware of the concept of local variables. It looks as though both buf
and str
could be local variables (and str
replaced by the sb
method parameter). Try changing your code to this:
public void run()
{
while(true)
{
try {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < 100; i++) {
buf.append(hello + (myint++));
}
buf.append("\n");
adapter.setData(buf.toString());
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(TestThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
public boolean setData(String str){
if(str != null && !str.equalsIgnoreCase("")){
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("inside run.....");
System.out.println("str length:- "+str.length());
//do sth after this..
}
}
And remove the instance or class declarations of buf
and str
. If you actually need them outside the methods, try doing so via return values or, if all else fails, use synchronization.
Upvotes: 2
Reputation: 64404
The problem is that you aren't synchronizing at all. For example, the "str" field is being read from one thread and simultaneously updated from another thread, without any synchronization.
(It would help if you showed a complete and runnable example instead of just the parts you think are interesting.)
Upvotes: 0
Reputation: 57658
That is because the str is a class variable. If you don't have a reason for using another reference for sb, try this:
public boolean setData(final String str){
if(str != null && !str.equalsIgnoreCase("")){
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("inside run.....");
System.out.println("str length:- "+str.length());
//do sth after this..
}
}
Upvotes: 2