# 多线程中并发问题

When i use cycle sentence to run two Threads it shows me that problem:java.lang.Thread.run(Thread.java:745) but i figure it out use two methods:\first if i dont run the application just debug it and use breakpoint it would be ok . second based on my demo just has two threads so i could copy this part of code "

    new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt();
+ " has put data:" + data);
new A().get();
new B().get();
}
}).start();

"

for twice it would also be ok .

all my demo code is below:

    package 多线程;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

private static int data = 0;
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
@Override
public void run() {
int data = new Random().nextInt();
+ " has put data:" + data);
new A().get();
new B().get();
}
}).start();
}
}

static class A {
public void get() {
+ "get data:" + data);
}
}

static class B {
public void get() {
+ "get data:" + data);
}
}
}

and the right result should be like below: Thread-1 has put data :-1188249922 Thread-0 has put data :1024718434 A from Thread-0 get data :1024718434 B from Thread-0 get data :1024718434 A from Thread-1 get data :-1188249922 B from Thread-1 get data :-1188249922

but the bug is below:Thread-1 has put data :-807205084 Thread-0 has put data :-976943511 A from Thread-0 get data :-976943511

   Exception in thread "Thread-1" B from Thread-0 get data :-976943511
java.lang.NullPointerException
at 多线程.ThreadScopeShareData$A.get(ThreadScopeShareData.java:33) at 多线程.ThreadScopeShareData$1.run(ThreadScopeShareData.java:22)
at java.lang.Thread.run(Thread.java:745)

As far as i know the Thread-1 would totally change and kill the thread-0 so it would appear a nullPointerException . but i am not sure.

-

Not clean in which cases you are not getting the expected result – ravthiru Aug 25 at 3:57
i meant :if i run this demo it would except a NullPointerException . but i based on my current code , i have two solutions .First is use "debug" command and put some breakpoint in it rather than "run" command . second, if i copy the thread part code for twice rather than use cycle sentence. it would be ok. but i dont know why the Thread was messed up . – qiaopan Ma Aug 25 at 13:05

Since you use threadDataMap in multiple threads use ConcurrentHashMap instead of HashMap.

-

thank u very much .and u r right if i use ConcurrentHashMap it would be ok, but could u tell me why it would be messed up if i use just HashMap . – qiaopan Ma 2 days ago
The cause is in concurrent changing of HashMap internal state. – Konstantin Labun 2 days ago
Most likely it is the result of concurrent initiation: when thread-1 and thread-0 at same time call put() on empty map, each of them start to create it's own hash-table and since Thread-0 was second to finish this action, it overwritten already created hash-table by Thread-1. So when you try to get data by key 'Thread-1' it returns null. – Konstantin Labun 2 days ago
i understand now the possible reason. but i am confused with the sequence during i debug the code below,the order is first i =0 then create a new Thread instance , then go to start() method, after that i= 1 create another new Thread instance then go to start method . after both finished , it goes to the run() method. : for (int i = 0; i < 2; i++) { new Thread(new Runnable() { @Override public void run() { } }).start();} – qiaopan Ma 2 days ago
i think the sequence maybe should be like this : after i=0 , it create a new Thread instance then , just go to start() and go to run() method. after this , i=1 , it create another new Thread instance then go to its start() method and go to this run() method. and when i copy this code:new Thread(new runnable(){@override public void run(){}}).start(); twice , the sequence is like what i described . and maybe that is the reason. I really want to know why if i use "for" cycle the run order would be like that . – qiaopan Ma 2 days ago

You have to understand that this static method Thread.currentThread()Returns a reference to the currently executing thread object.

So if you execute it the first time it is going to return the main thread, which is the main class, before event spawning the thread number 1.Java Doc for Thread.currentThread()

You should use the Thread.setName(String name) to explicitely set the names of threads.

Try this.

    import java.util.HashMap;
import java.util.Map;
import java.util.Random;

private static int data = 0;
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
@Override
public void run() {
int data = new Random().nextInt();
+ " has put data:" + data);
new A().get();
new B().get();
}
});
t.setName(i);
t.start();
}
}
-
I don't think your analysis is right. The run() method is indeed called by 2 threads and not by 'main' thread. The code that he wrote in question is correct but as it was messed up by hashmap since it wasn't handled the way he expected, he got wrong output. But regardless, I don't think it's due to the reason you gave above, IMHO – Sanjeev Dhiman Aug 25 at 6:13
thank both of u . but i am afraid Sanjeev Dhiman is right . i tried to run Two threads rather than one . so based on this . could u find any clues about my question. – qiaopan Ma 2 days ago

#### 访问量、并发、TPS

2018-05-20 20:55:53

2018-04-09 14:41:31

#### Javascript中类似多线程，并发解决方案

2008-05-07 15:27:00

#### 多线程_练习

2016-12-09 14:13:21

#### 多线程共享资源

2016-09-01 19:50:28

#### 多线程的几个简单问题

2014-01-23 19:55:42

#### 多线程

2017-12-02 00:04:26

#### java高并发1——多线程之旅序

2018-03-09 21:41:38

#### 多线程的基础知识

2017-10-11 14:52:36

#### Java 并发（一）——线程和同步

2014-04-27 17:32:25