Tag Archives: Concurrent programming

[Solved] Java Run Error: For input string: “XXX”

Background

Today, a small partner of front-end joint commissioning said that an interface reported an error.

I first glanced at the code and found no problem.

First post the code of the place where the error is reported

...
IntegralRecord integralRecord = new IntegralRecord();
integralRecord.setUid(uid);
integralRecord.setLinkType(IntegralRecordConstants.TYPE_SIGN);
integralRecord.setTitle(IntegralRecordConstants.INTEGRAL_TASK);
integralRecord.setIntegral(Integer.parseInt(amount));
integralRecord.setStatus(1);
integralRecord.setType(IntegralRecordConstants.TYPE_ADD); 
integralRecord.setMark(StrUtil.format("Free {} points for completing tasks", amount));
userIntegralRecordService.save(integralRecord);
...

Problem location
There is no choice but to debugger a line to run.

After running to

integralRecord.setIntegral(Integer.parseInt(amount));

This line, then reported an error message For input string.

This line of code, when I look at it, just does a conversion operation on the type.

Is there something wrong with the passed data?

I ran it again and found that amount=2.00

Explanation: Because the amount is shared by several places, considering that there may be a decimal situation, a String is used in the front-end pass, and the back-end uses the corresponding type for conversion according to the actual situation.

When converting, it is indeed this line that has a problem.

The specific test situation is shown below:

Then we changed it to

amount=”2″

The results are as follows

Then the problem can be defined because integer cannot recognize the case with decimals during conversion.

Problem follow up

Integer.parseInt source code

We found that parseInt finally called the following code.

public static int parseInt(String s, int radix) throws NumberFormatException{

        if (s == null) {
            throw new NumberFormatException("null");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }

        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }

        boolean negative = false;
        int i = 0, len = s.length();
        int limit = -Integer.MAX_VALUE;

        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {
                    negative = true;
                    limit = Integer.MIN_VALUE;
                } else if (firstChar != '+') {
                    throw NumberFormatException.forInputString(s);
                }

                if (len == 1) { // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                }
                i++;
            }
            int multmin = limit/radix;
            int result = 0;
            while (i < len) {
                int digit = Character.digit(s.charAt(i++), radix);
                if (digit < 0 || result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
            return negative ?result : -result;
        } else {
            throw NumberFormatException.forInputString(s);
        }
    }

Source code positioning

In the code, we can see that an error will be reported if the range is no longer specified

int digit = Character.digit(s.charAt(i++), radix);
  if (digit < 0 || result < multmin) {
    throw NumberFormatException.forInputString(s);
}

java.lang.Character.digit(char ch, int radix) method :

Returns the value of the character ch in the specified base, if the base is not in the range MIN_RADIX ≤ base ≤ MAX_RADIX or if the value of the channel is not a valid number in the specified base -1, then it is returned.

The value of radix is 10, this is because the conversion Int type is when the single character 0~9.

So if the value is not a number between 0~9 an error will be reported.

The exception thrown is forInputString.

Solution:
String interception
In this example, it is clear that only the integer part is needed, so you can specify the character “.” based on the to intercept.

Then you can convert it and it’s done.

Borrowing from a third party
Here we recommend using the NumberUtil from the hutool toolkit

You can convert similar numbers directly.

Method: NumberUtil.parseInt

 String val ="2.00";
 int i = NumberUtil.parseInt(val);

Type conversion

Because it can be determined that the value must be of numerical type.

So it can be directly converted to BigDecimal type.

BigDecimal has an intValue method, which can be called after direct conversion

 String val ="2.00";
 int i = new BigDecimal(val).intValue();

[go] solve the fatal error of go: concurrent map writes map non concurrent security

Map is not concurrency safe, when there are multiple concurrent growths reading and writing the same map  
A panic error occurs

concurrent map writes

For example, this error occurs in the following code:

var mMap map[int]int

func TestMyMap(t *testing.T) {
    mMap = make(map[int]int)

    for i := 0; i < 5000; i++ {
        go func() {
            mMap[i] = i
        }()
        go readMap(i)
    }
}
func readMap(i int) int {
    return mMap[i]
}

There are many ways to solve this problem. Now we use read-write lock,

Concurrent access to map is not safe, and undefined behavior will appear, leading to program exit. Therefore, if you want to access the map concurrently in multiple coroutines, you must provide some synchronization mechanism. Generally, you can control the concurrent access to the map by reading and writing the lock sync.rwmutex. Encapsulating the map and sync.rwmutex can realize the secure concurrent access to the map

Code after transformation

type SMap struct {
    sync.RWMutex
    Map map[int]int
}

func (l *SMap) readMap(key int) (int, bool) {
    l.RLock()
    value, ok := l.Map[key]
    l.RUnlock()
    return value, ok
}

func (l *SMap) writeMap(key int, value int) {
    l.Lock()
    l.Map[key] = value
    l.Unlock()
}

var mMap *SMap

func TestMyMap(t *testing.T) {
    mMap = &SMap{
        Map: make(map[int]int),
    }

    for i := 0; i < 5000; i++ {
        go func() {
            mMap.writeMap(i, i)
        }()
        go readMap(i)
    }
}
func readMap(i int) (int, bool) {
    return mMap.readMap(i)
}

  There are three ways:

1. Use channel
2. Use sync. Map
3. Use map but lock it

Asynchronous callback case of Java callback function

1. Callback function classification

Callback function distinction: synchronous callback and asynchronous callback

Synchronous callback: the meaning is only to complete the method call;

Asynchronous call: concurrency can be realized, and the main business thread can be released in time; asynchronous thread completes the work, executes callback function, and completes the aftermath work; the execution efficiency is improved.

2. Code examples

1. Note testing

package com.callback2;

public class AsyncCallBack {

    public static void main(String[] args) {
        System.out.println("Start of the main business thread ID:" + Thread.currentThread().getId());
        System.out.println("------------------");

        Son son = new Son();
        Mother mother = new Mother(son);

        mother.notice();
        son.writeHomeWork();

        System.out.println("End of the main business thread ID:" + Thread.currentThread().getId()+"\n");

    }

}

2. Mother

package com.callback2;

public class Mother {
    private Son son;
    public Mother(Son son) {
        this.son = son;
    }

    public void notice() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Notify the mother of the thread ID." + Thread.currentThread().getId());
                cookFood("Bread");
            }
        }).start();
    }

    public void cookFood(String bread) {
        System.out.println("Current cooking thread ID." + Thread.currentThread().getId());
        try {
            System.out.println("Mother Baking" + bread + "...");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Mother has baked the bread");
        String message = "Ming, come and eat!";

        son.callback(message);

    }

}

3. My son Xiao Ming

package com.callback2;

public class Son {
    private String status = "";

    public void writeHomeWork() {
        System.out.println("Xiaoming writing homework thread ID: " + Thread.currentThread().getId());
        System.err.println("Ming is writing his homework...") ;
        setStatus("Writing homework");
    }


    public void callback(String message) {
        System.out.println("Callback Xiaoming meal thread ID: " + Thread.currentThread().getId());
        System.err.println(message);
        System.err.println("Okay, coming right up!") ;
        System.out.println("Ming started eating!") ;
        setStatus("Eating in progress");
        System.out.println("Xiaoming executing meal thread ID." + Thread.currentThread().getId());
    }

    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
}

4. Implementation results

Business Main Thread Start ID: 1
------------------
Xiaoming writing homework thread ID: 1
Xiaoming writing homework in progress...
Business main thread end ID:1

Notify mother thread ID:12
Currently cooking thread ID:12
Mother baking bread...
Mother baked the bread
Callback to Xiaoming to eat Thread ID: 12
Ming, come and eat!
Okay, coming right up!
Ming starts eating!
Xiaoming executes meal thread ID: 12

5. Result analysis

1) Xiao Ming uses the main thread to do his homework (if he can’t finish it, he doesn’t need to care);

2) Mother uses the new thread to cook [concurrent], mother finishes the meal, executes the callback function, and notifies Xiao Ming to eat;

3) Xiao Ming uses a new thread and starts to eat.