Android项目中的处理程序:线程安全

时间:2016-11-30 19:50:16

标签: android multithreading thread-safety handler android-looper

我在Android项目中使用Handler来回调主/ ui线程。

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]
  after_action :verify_authorized, except: [:index, :show]

  def index
    @meta_title = "Blog"
    @meta_description = "blog description"
    @posts = Post.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 4)
  end

  def show
    @meta_title = @post.title
    @meta_description = @post.description
  end

  def new
    @meta_title = "Add New Blog"
    @meta_description ="Add a new blog."
    @post = Post.new
    authorize @post
  end

  def edit
    @meta_title = "Edit Blog"
    @meta_description ="Edit an existing blog."
    authorize @post
  end

  def create
    @post = Post.new
    @post.update_attributes(permitted_attributes(@post))
    @post.user = current_user if user_signed_in?

    authorize @post

    if @post.save
      redirect_to @post, notice: 'Post was successfully created.'
    else
      render :new
    end
  end

  def update
    @post = Post.find(params[:id])
    authorize @post
    if @post.update_attributes(permitted_attributes(@post))
      redirect_to @post, notice: 'Post was successfully updated.'
    else
      render :edit
    end
  end

  def destroy
    if @post.present?
      @post.destroy
      authorize @post
    else
      skip_authorization
    end

    redirect_to posts_url, notice: 'Post was successfully deleted.'
  end

  private
  # Use callbacks to share common setup or constraints between actions.
  def set_post
    @post = Post.find(params[:id])
  end

  # Only allow the white list through.
  def post_params
    params.require(:post).permit(policy(@post).permitted_attributes)
  end
end

当我创建处理程序对象,即mHandler时,我正在检查处理程序是否已经存在。如果没有,那么我正在创建处理程序,即使用单例模式。我的问题是:处理程序对象线程的创建是否安全?

感谢。

2 个答案:

答案 0 :(得分:1)

不,此代码不是线程安全的。

但是问题不是处理程序本身,而是使用的创建模式。 如果您在此处报告的代码被两个不同的线程同时调用,则可能会发生严重竞争,其中将创建两个不同的对象(在本例中为Handler)。 如果您确定始终由同一线程调用此代码,则可以安全地使用它。

顺便说一下,这与懒惰的Singleton创建是相同的问题,通常可以通过以下方式解决:

if( mHandler == null )
{
    syncronized( this )
    {
        if( mHandler == null )
            mHandler = new Handler(Looper.getMainLooper());
    }
}

“这”是一个同步对象,可以是类容器或其他任何对象。

答案 1 :(得分:0)

句柄是线程安全的。

要处理与工作线程的更复杂的交互,您可以考虑在工作线程中使用Handler来处理从UI线程传递的消息。 (DOC-Worker Threads

通常,您为新线程创建一个Handler,但您也可以创建一个连接到现有线程的Handler。将Handler连接到UI线程时,处理消息的代码在UI线程上运行(Android Documetation

相关问题