Java:生产者-消费者两个线程停止工作,冻结

时间:2020-06-02 10:38:36

标签: java multithreading concurrency

我有这段代码,它从第一个数组中获取数据,然后将其放入第二个数组中,然后从第一个数组中删除它。它可以正常工作一会儿,但随后停止,同时第一个数组中仍有要粘贴的值:

public class EditProfileActivity extends AppCompatActivity {

    ImageView mClose, mCheckmark, mImageProfile;
    TextView mChangePhoto;
    MaterialEditText mName, mUsername, mBio;

    private String mUsername1;

    FirebaseUser mFirebaseUser;

    private Uri mImageUri;
    StorageReference mStorageReference;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_profile);

        mClose = findViewById(R.id.close);
        mCheckmark = findViewById(R.id.post_checkmark);
        mImageProfile = findViewById(R.id.image_profile);
        mChangePhoto = findViewById(R.id.text_view_change_profile_picture);
        mName = findViewById(R.id.fullname);
        mUsername = findViewById(R.id.username);
        mBio = findViewById(R.id.bio);

        mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        mStorageReference = FirebaseStorage.getInstance().getReference("uploads");

        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users").child(mFirebaseUser.getUid());
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                User user = dataSnapshot.getValue(User.class);
                if (user != null) {
                    mName.setText(user.getFullname());
                    mUsername.setText(user.getUsername().toLowerCase());
                    mBio.setText(user.getBio());
                    Glide.with(getApplicationContext()).load(user.getImageurl()).into(mImageProfile);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        mClose.setOnClickListener(v -> new AlertDialog.Builder(EditProfileActivity.this)
                .setTitle("Exit without saving changes?")
                .setPositiveButton("Yes", (dialog, which) -> {
                    finish();
                }).setNegativeButton("No", null).show());

        mChangePhoto.setOnClickListener(v -> CropImage.activity()
                .setAspectRatio(1, 1)
                .setCropShape(CropImageView.CropShape.OVAL)
                .start(EditProfileActivity.this));

        mImageProfile.setOnClickListener(v -> CropImage.activity()
                .setAspectRatio(1, 1)
                .setCropShape(CropImageView.CropShape.OVAL)
                .start(EditProfileActivity.this));

        mCheckmark.setOnClickListener(v -> {

            String str_name = mName.getText().toString();
            String str_username = mUsername.getText().toString();
            String str_bio = mBio.getText().toString();

            if (TextUtils.isEmpty(str_username) || TextUtils.isEmpty(str_bio) || TextUtils.isEmpty(str_name)) {
                Toast.makeText(this, "Please fill in all fields", Toast.LENGTH_SHORT).show();
            } else if (str_username.length() > 20) {
                Toast.makeText(this, "Username cannot contain more than 20 characters", Toast.LENGTH_SHORT).show();
            } else {
                updateProfile(mName.getText().toString(), mUsername.getText().toString().toLowerCase(), mBio.getText().toString());
            }
        });
    }

    private void updateProfile(String fullname, String username, String bio) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users").child(mFirebaseUser.getUid());

        mUsername1 = username.replaceAll("\\s+", "");
        mUsername1 = username.replaceAll("[^\\w]", "");

        DatabaseReference reference1 = FirebaseDatabase.getInstance().getReference("Users");
        reference1.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                boolean ifUserNameExists = false;
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    User user = snapshot.getValue(User.class);
                    if (user != null) {
                        if (user.getUsername().equals(mUsername1.toLowerCase())) {
                            Toast.makeText(EditProfileActivity.this, "That username has already been taken. Try another", Toast.LENGTH_SHORT).show();
                            ifUserNameExists = true;
                        }
                    }
                }

                if (!ifUserNameExists) {
                    HashMap<String, Object> hashMap = new HashMap<>();
                    hashMap.put("fullname", fullname);
                    hashMap.put("username", mUsername1.toLowerCase());
                    hashMap.put("bio", bio);

                    reference.updateChildren(hashMap);
                    Toast.makeText(EditProfileActivity.this, "Username has been changed", Toast.LENGTH_LONG).show();
                    finish();
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

输出:

 mCheckmark.setOnClickListener(v -> {

        String str_name = mName.getText().toString();
        String str_username = mUsername.getText().toString();
            String str_bio = mBio.getText().toString();

            if (TextUtils.isEmpty(str_username) || TextUtils.isEmpty(str_bio) || TextUtils.isEmpty(str_name)) {
                Toast.makeText(this, "Please fill in all fields", Toast.LENGTH_SHORT).show();
            } else if (str_username.length() > 20) {
                Toast.makeText(this, "Username cannot contain more than 20 characters", Toast.LENGTH_SHORT).show();
            } else if (!mUser.getUsername().equals(mUsername.getText().toString().toLowerCase()) && !mUser.getFullname().equals(mName.getText().toString()) && !mUser.getBio().equals(mBio.getText().toString())) {
                updateProfile(mName.getText().toString(), mUsername.getText().toString().toLowerCase(), mBio.getText().toString());
            }
        });

1 个答案:

答案 0 :(得分:1)

UsbCutThread0迭代到usb.getData().size()

              for (int i = 0; i < usb.getData().size(); i++) {

在循环中,您将usb.getData()的大小由usb.eraseValue()更改。这显然会影响迭代的数量。在您的情况下,您将获得3次迭代,直到i == usb.getData().size()true并退出循环为止。

当您将整个内容放入lock.wait()时,另一个线程进入while (true)。这是您的程序不会终止的地方。

要解决第一个问题,您只需要迭代一个固定的限制即可:

              int n = usb.getData().size();
              for (int i = 0; i < n; i++) {

我认为第二个问题实际上对您来说不是问题,而是您想要的。所以我就在这里停止。

相关问题