Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android에서 synchronizedSet으로 스레드 안전한 Set 만들기 – 단계별 구현 가이드

Android에서 synchronizedSet이란?

Collections.synchronizedSet()은 지정된 Set 객체를 감싸서 스레드 안전(thread-safe)한 Set을 반환하는 Java 유틸리티 메서드입니다. 여러 스레드가 동시에 동일한 컬렉션에 접근할 때 발생할 수 있는 데이터 불일치나 ConcurrentModificationException 같은 문제를 방지할 수 있습니다.

이 글에서는 Android 앱에서 synchronizedSet을 활용해 사용자 입력 데이터를 안전하게 저장하고 ListView에 표시하는 방법을 단계별로 살펴보겠습니다.


구현 단계

1단계 – 새 프로젝트 생성

Android Studio에서 File ⇒ New Project로 이동하여 새 프로젝트를 생성하고, 프로젝트 생성에 필요한 모든 세부 정보를 입력합니다.

2단계 – 레이아웃 작성

res/layout/activity_main.xml 파일에 아래 코드를 추가합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "https://schemas.android.com/apk/res/android"
   xmlns:tools = "https://schemas.android.com/tools"
   android:layout_width = "match_parent"
   android:layout_height = "match_parent"
   tools:context = ".MainActivity"
   android:orientation = "vertical">
   <EditText
      android:id = "@+id/name"
      android:layout_width = "match_parent"
      android:hint = "Enter Name"
      android:layout_height = "wrap_content" />
   <LinearLayout
      android:layout_width = "wrap_content"
      android:layout_height = "wrap_content">
      <Button
         android:id = "@+id/save"
         android:text = "Save"
         android:layout_width = "wrap_content"
         android:layout_height = "wrap_content" />
      <Button
         android:id = "@+id/refresh"
         android:text = "Refresh"
         android:layout_width = "wrap_content"
         android:layout_height = "wrap_content" />
   </LinearLayout>
   <ListView
      android:id = "@+id/listView"
      android:layout_width = "match_parent"
      android:layout_height = "wrap_content">
   </ListView>
</LinearLayout>

위 레이아웃에는 이름을 입력받는 EditText, 데이터를 저장하는 Save 버튼, 변경 사항을 갱신하는 Refresh 버튼, 그리고 결과를 표시하는 ListView가 포함되어 있습니다. 사용자가 Save 버튼을 클릭하면 입력된 이름이 Set에 저장되고, Refresh 버튼을 누르면 ListView에 최신 목록이 반영됩니다.

3단계 – MainActivity 코드 작성

src/MainActivity.java 파일에 아래 코드를 추가합니다.

package com.example.andy.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
public class MainActivity extends AppCompatActivity {
   EditText name;
   ArrayAdapter arrayAdapter;
   ArrayList<String> array_list;
   Set set = new TreeSet();
   private ListView listView;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      array_list = new ArrayList<String>();
      name = findViewById(R.id.name);
      listView = findViewById(R.id.listView);
      findViewById(R.id.refresh).setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            arrayAdapter.notifyDataSetChanged();
            listView.invalidateViews();
            listView.refreshDrawableState();
         }
      });
      findViewById(R.id.save).setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            if (!name.getText().toString().isEmpty()) {
               set.add(name.getText().toString());
               Set syncSet = Collections.synchronizedSet(set);
               array_list.clear();
               array_list.addAll(syncSet);
               arrayAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, array_list);
               listView.setAdapter(arrayAdapter);
               Toast.makeText(MainActivity.this, "Inserted", Toast.LENGTH_LONG).show();
            } else {
               name.setError("Enter NAME");
            }
         }
      });
   }
}

핵심 코드 설명

  • TreeSet으로 Set을 선언하여 요소가 자동으로 정렬되고 중복 없이 저장되도록 합니다.
  • Collections.synchronizedSet(set)을 호출하면 원본 Set을 감싼 동기화된 Set이 반환됩니다. 이후 모든 접근은 내부적으로 동기화 처리됩니다.
  • Save 버튼 클릭 시 입력값이 비어 있으면 에러 메시지를 표시하고, 값이 있으면 Set에 추가한 뒤 어댑터를 통해 ListView를 갱신합니다.

앱 실행 및 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 Android 모바일 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 아이콘을 클릭합니다. 실행 옵션에서 자신의 모바일 기기를 선택하면 기기 화면에 앱이 표시됩니다.

Android에서 synchronizedSet으로 스레드 안전한 Set 만들기 – 단계별 구현 가이드

위 실행 결과에서 이름을 입력하고 Save 버튼을 누를 때마다 TreeSet 요소로 데이터가 삽입되어 ListView에 정렬된 형태로 표시되는 것을 확인할 수 있습니다.

마무리

synchronizedSet은 멀티스레드 환경에서 컬렉션을 안전하게 공유해야 할 때 유용한 도구입니다. 다만 반복(iteration) 작업 시에는 수동으로 동기화 블록을 사용해야 하며, 성능이 중요한 최신 앱이라면 ConcurrentHashMap.newKeySet() 같은 동시성 컬렉션도 함께 고려해 보시기 바랍니다.