Java线程,错误计数器
我在代码段下面运行,得到了意想不到的行为。也许它是以正确的方式工作,但我需要让它以另一种方式工作。详情如下Java线程,错误计数器,java,multithreading,Java,Multithreading,我在代码段下面运行,得到了意想不到的行为。也许它是以正确的方式工作,但我需要让它以另一种方式工作。详情如下 import java.util.ArrayList; import java.util.List; public class TaskExample { public static void main(String[] args) throws InterruptedException { final PositionHolder holder = new PositionH
import java.util.ArrayList;
import java.util.List;
public class TaskExample {
public static void main(String[] args) throws InterruptedException {
final PositionHolder holder = new PositionHolder();
final List<Integer> data = new ArrayList<Integer>();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 20; i++) {
holder.setPosition(i);
Thread t = new Thread() {
@Override
public void run() {
data.add(holder.getPosition());
}
};
t.start();
threads.add(t);
}
for (Thread thread : threads) {
thread.join();
}
for(int i : data){
System.out.println(i);
}
}
}
class PositionHolder {
int position = 0;
public void setPosition(int position) {
this.position = position;
}
public int getPosition() {
return this.position;
}
}
import java.util.ArrayList;
导入java.util.List;
公共类任务示例{
公共静态void main(字符串[]args)引发InterruptedException{
最终位置保持架=新位置保持架();
最终列表数据=新的ArrayList();
List threads=new ArrayList();
对于(int i=0;i<20;i++){
固定位置(i);
线程t=新线程(){
@凌驾
公开募捐{
data.add(holder.getPosition());
}
};
t、 start();
添加(t);
}
对于(线程:线程){
thread.join();
}
for(int i:数据){
系统输出打印LN(i);
}
}
}
类职位持有者{
int位置=0;
公共无效设置位置(内部位置){
这个位置=位置;
}
public int getPosition(){
返回此位置;
}
}
我得到的结果是:
1012988665421616161819191919
为什么??我想得到:
1234。。。。。。二十
是否有导入此代码段的选项?请尝试此代码;)
import java.util.ArrayList;
导入java.util.List;
公共类ogr
{
公共静态void main(字符串[]args)引发InterruptedException{
最终位置保持架=新位置保持架();
最终列表数据=新的ArrayList();
对于(int i=0;i<20;i++){
固定位置(i);
线程t=新线程(){
@凌驾
公开募捐{
data.add(holder.getPosition());
}
};
t、 start();
t、 join();
}
for(int i:数据){
系统输出打印LN(i);
}
}
}
类职位持有者
{
int位置=0;
公共无效设置位置(内部位置){
这个位置=位置;
}
public int getPosition(){
返回此位置;
}
}
无法保证holder.getPosition()将获得使用holder.setPosition(i)设置的相同位置值,因为getHolder调用是不同线程的一部分,并且由多个线程调用。这是因为您在所有线程中共享同一占位符。如果您希望获得所需的输出,我建议为每个线程使用不同的占位符实例
import java.util.ArrayList;
import java.util.List;
public class TaskExample {
public static void main(String[] args) throws InterruptedException {
final List<Integer> data = new ArrayList<Integer>();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 20; i++) {
// Create new instance
final PositionHolder holder = new PositionHolder(i);
Thread t = new Thread() {
@Override
public void run() {
data.add(holder.getPosition());
}
};
t.start();
threads.add(t);
for (Thread thread : threads) {
thread.join();
}
for(int i : data){
System.out.println(i);
}
}
class PositionHolder {
private int position = 0;
public PositionHolder(int position) {
this.position = position;
}
public int getPosition() {
return this.position;
}
}`
import java.util.ArrayList;
导入java.util.List;
公共类任务示例{
公共静态void main(字符串[]args)引发InterruptedException{
最终列表数据=新的ArrayList();
List threads=new ArrayList();
对于(int i=0;i<20;i++){
//创建新实例
最终定位器=新定位器(i);
线程t=新线程(){
@凌驾
公开募捐{
data.add(holder.getPosition());
}
};
t、 start();
添加(t);
对于(线程:线程){
thread.join();
}
for(int i:数据){
系统输出打印LN(i);
}
}
类职位持有者{
私有int位置=0;
公共职位持有者(内部职位){
这个位置=位置;
}
public int getPosition(){
返回此位置;
}
}`
如果没有像join()这样的同步机制,就无法保证线程的执行顺序(请参阅Fincio提出的代码)
由于对所有线程使用相同的PositionHolder
对象,因此,变量position
会被启动的每个线程修改。尝试对对象而不是int执行相同操作可能会导致ConcurrentAccessException
同样,每个螺纹都应该有自己的PositionHolder
实例(如Saket提供的代码)但是,即使这样,也不能保证线程的执行顺序。使用线程编程有时需要一些技巧来提高线程效率。显然,这并不是那么自然。例如,检查以下内容
import java.util.ArrayList;
import java.util.List;
public class ogr{
public static void main(String[] args) throws InterruptedException {
ArrayList<PositionHolder> holders=new ArrayList<PositionHolder>();
final PositionHolder holder = new PositionHolder();
final List<Integer> data = new ArrayList<Integer>();
for (int i = 0; i < 20; i++) {
Thread t = new Thread() {
@Override
public void run() {
data.add(getSetPosition());
}
};
holders.add(holder)
t.start();
}
for (Thread thread : threads) {
thread.join();
}
SortByPosition(holders); //you can implement this easy by sorting arraylist by their positions
for (int i : data) {
System.out.println(i);
}
}
}
class PositionHolder{
static int staticPosition=0;
int position = 0;
public int synchronized getSetPosition() {
this.position = staticPosition++;
return position;
}
// public void setPosition(int position) {
// this.position = position;
// }
public int getPosition() {
return this.position;
}
}
import java.util.ArrayList;
导入java.util.List;
公共类ogr{
公共静态void main(字符串[]args)引发InterruptedException{
ArrayList holders=新的ArrayList();
最终位置保持架=新位置保持架();
最终列表数据=新的ArrayList();
对于(int i=0;i<20;i++){
线程t=新线程(){
@凌驾
公开募捐{
data.add(getSetPosition());
}
};
持有人。添加(持有人)
t、 start();
}
对于(线程:线程){
thread.join();
}
SortByPosition(holders);//您可以通过按位置对arraylist进行排序来轻松实现这一点
for(int i:数据){
系统输出打印LN(i);
}
}
}
类职位持有者{
静态int staticPosition=0;
int位置=0;
public int synchronized getSetPosition(){
this.position=staticPosition++;
返回位置;
}
//公共无效设置位置(内部位置){
//这个位置=位置;
// }
public int getPosition(){
返回此位置;
}
}
你需要同步对你的数据的调用。如何做?当我添加:
公共同步的void run(){data.add(holder.getPosition();}我得到了:929931011451515161819191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191你需要一个接一个地同步运行线程,因为你不知道哪个1将首先获得处理器。@Mena-我认为,他的设计有缺陷,他必须在循环本身内同步,否则他可能会得到unpr
import java.util.ArrayList;
import java.util.List;
public class ogr{
public static void main(String[] args) throws InterruptedException {
ArrayList<PositionHolder> holders=new ArrayList<PositionHolder>();
final PositionHolder holder = new PositionHolder();
final List<Integer> data = new ArrayList<Integer>();
for (int i = 0; i < 20; i++) {
Thread t = new Thread() {
@Override
public void run() {
data.add(getSetPosition());
}
};
holders.add(holder)
t.start();
}
for (Thread thread : threads) {
thread.join();
}
SortByPosition(holders); //you can implement this easy by sorting arraylist by their positions
for (int i : data) {
System.out.println(i);
}
}
}
class PositionHolder{
static int staticPosition=0;
int position = 0;
public int synchronized getSetPosition() {
this.position = staticPosition++;
return position;
}
// public void setPosition(int position) {
// this.position = position;
// }
public int getPosition() {
return this.position;
}
}