Android Thread

线程同步【线程安全】

  线程同步,指的是多线程使用共享资源,程序世界会出现错误,那么这种错误为线程不安全。因此需要线程同步处理。

  线程同步使用锁机制来达到线程同步的目的。

  JAVA中可以使用synchronized关键字,达到代码级别或者方法级别的同步。

  在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

synchronized方法级别,那么同步锁为当前方法所在的对象


        //方法级别同步,锁对象为改方法所在的对象
        public synchronized void server1()
        {

        }

synchronized代码级别,那么同步锁为自己定义的对象


        public void server1()
        {
            //代码段级别同步,锁对象为任意对象
            // 但是需要保证所有调用该代码段的线程,都看到的是同一个对象
            synchronized (object) {
               //同步范围
            }
        }

案例


package com.hzj163.mythread;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class F3 extends Fragment {
    //共享资源
    int count = 1000;
    //同步锁对象
    Object object = new Object();

    //四个变量记录四个线程所获得的资源
    int r1 = 0;
    int r2 = 0;
    int r3 = 0;
    int r4 = 0;


    //UI
    View view;
    TextView textView1;
    TextView textView2;
    TextView textView3;
    TextView textView4;
    TextView textView5;
    Button button1;
    //消息对象
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    textView1.setText(msg.obj.toString());
                    r1 = Integer.parseInt(msg.obj.toString());
                    break;
                case 2:
                    textView2.setText(msg.obj.toString());
                    r2 = Integer.parseInt(msg.obj.toString());
                    break;
                case 3:
                    textView3.setText(msg.obj.toString());
                    r3 = Integer.parseInt(msg.obj.toString());
                    break;
                case 4:
                    textView4.setText(msg.obj.toString());
                    r4 = Integer.parseInt(msg.obj.toString());
                    break;
            }


            textView5.setText(count + "");
            //消息对象观察资源,如果资源为0那么初始化
            if (count == 0) {
                timer1.cancel();
                timer2.cancel();
                timer3.cancel();
                timer4.cancel();
                button1.setEnabled(true);
                r1 = 0;
                r2 = 0;
                r3 = 0;
                r4 = 0;
                //重新补充资源
                count = 1000;
            }
        }
    };


    //四个线程
    Timer timer1;
    Timer timer2;
    Timer timer3;
    Timer timer4;

    //执行任务
    class MyTimeTask extends TimerTask {
        //消息类型值
        int what;
        //传递进来的每个任务的资源数量
        int rValue;

        public MyTimeTask(int what, int rValue) {
            this.what = what;
            this.rValue = rValue;

        }

        @Override
        public void run() {
            //同步任务
            synchronized (object) {

                //判断公共资源
                if (count > 0) {
                    //添加资源
                    rValue++;
                    //减少公共资源
                    count--;
                    //发送消息
                    Message message = handler.obtainMessage();
                    message.what = what;
                    message.obj = rValue;
                    message.sendToTarget();
                }
            }
        }
    }


    public void btn1(View view) {

        //实例化线程
        timer1 = new Timer();
        timer2 = new Timer();
        timer3 = new Timer();
        timer4 = new Timer();
        //随机数实例化,造成每个线程每次执行的毫秒数不一样
        Random random = new Random();
        int random1 = random.nextInt(100) + 100;
        int random2 = random.nextInt(100) + 100;
        int random3 = random.nextInt(100) + 100;
        int random4 = random.nextInt(100) + 100;

        //线程开始执行任务
        timer1.schedule(new MyTimeTask(1, r1), 0, random1);
        timer2.schedule(new MyTimeTask(2, r2), 0, random2);
        timer3.schedule(new MyTimeTask(3, r3), 0, random3);
        timer4.schedule(new MyTimeTask(4, r4), 0, random4);

        button1.setEnabled(false);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        if (view == null) {
            view = inflater.inflate(R.layout.fragment_f3, container, false);
            textView1 = (TextView) view.findViewById(R.id.textView1);
            textView2 = (TextView) view.findViewById(R.id.textView2);
            textView3 = (TextView) view.findViewById(R.id.textView3);
            textView4 = (TextView) view.findViewById(R.id.textView4);
            textView5 = (TextView) view.findViewById(R.id.textView5);
            button1 = (Button) view.findViewById(R.id.button1);
            button1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    btn1(v);
                }
            });
        }
        return view;
    }


}