关于线程&锁

来源:互联网 发布:python 获取桌面路径 编辑:程序博客网 时间:2024/06/04 19:01

进程:一个正在执行的程序,每一个进程又有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元
线程:进程中一个独立的控制单元,线程控制进程执行。* 每一个线程都是个独立的执行路径*
线程创建方法:
方法一:

new Thread(){            @Override            public void run() {                for(int i=0;i<100;i++){                    Thread.currentThread().getName()+" "+i                }            }        }.start();

方法二:

class RunnableTest implements Runnable {        @Override        public void run() {            for (int i = 0; i < 100; i++) {                Thread.currentThread().getName() + " " + i            }        }    }new Thread(new RunnableTest()).start();

方法二避免了单继承的局限性。

方法三

Handler handler = new Handler();Runnable runnable = new Runnable() {   @Override   public void run() {    mPopupWindow.dismiss();   }};handler.postDelayed(runnable, POP_SHOW_TIME);

线程生命周期

1、新建(new Thread) new出实例,线程进入新建状态(未被启动)
2、就绪(runnable) 线程已经启动,正在等待被分配给cpu时间片,此时线程正在就绪队列中排队等候得到的CPU资源
3、运行(running)线程获得CPU资源正在执行任务,此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束
4、死亡(dead) 线程执行完毕或其他线程杀死,线程就进入死亡状态,线程不可能再进入就绪状态等待执行
自然终止:正常执行run()方法后终止
异常终止:调用stop()方法让一个线程终止运行

5、堵塞 (blocked) 由于某种原因导致正在运行的线程让出cpu并且暂停自己的执行,即进入堵塞状态
正在睡眠:用sleep方法可使线程进入睡眠方式,一个睡眠着的线程在指定的时间过去可进入就绪状态
正在等待:调用wait()方法, 调用notify()方法回到就绪状态
被另一个线程所阻塞:调用suspend()方法 调用resume()方法恢复

线程不安全
临界资源,多个线程共享的数据称为临界资源
多条语句操作同一个线程的共享数据,一个线程只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据错误。
解决方法:对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中其他线程不能进来。
注意一下两段代码 差别

class Ticket implements Runnable//extends Thread{    private  int tick = 100;    public void run()    {        while(true)        {            if(tick>0)            {                System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);            }        }    }//上面贴的一段代码可能打印出0 -1 -2class Ticket implements Runnable{    private  int tick = 1000;    Object obj = new Object();    public void run()    {        while(true)        {            synchronized(obj)            {                if(tick>0)                {                    //try{Thread.sleep(10);}catch(Exception e){}                    System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);                }            }        }    }}

懒汉式单例模要想线程安全,需要添加如下逻辑

class Single{    private static Single s = null;    private Single(){}    public static  Single getInstance()    {        if(s==null)        {            synchronized(Single.class)            {                if(s==null)                    //--->A;                    s = new Single();            }        }        return s;    }}

同步函数被静态修饰,使用的锁不是this,因为静态方法中也不可以定义this,静态方法进内存是不需要本类对象的。但一定有该类对应的字节码文件对象,类名.class。

deadlock 死锁
同步中嵌套同步

public class MainActivity extends AppCompatActivity {    public static final String TAG = "mrpeng";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Thread a = new Thread(new Lock1());        Thread b = new Thread(new Lock2());        a.start();        b.start();    }    class Lock1 implements Runnable{        @Override        public void run(){            try{                Log.e(TAG,"Lock1 running");                while(true){                    synchronized(DeadLock.obj1){                        Log.e(TAG, "Lock1 lock obj1");                        Thread.sleep(3000);//获取obj1后先等一会儿,让Lock2有足够的时间锁住obj2                        synchronized(DeadLock.obj2){                            Log.e(TAG, "Lock1 lock obj2");                        }                    }                }            }catch(Exception e){                e.printStackTrace();            }        }    }    class Lock2 implements Runnable{        @Override        public void run(){            try{                Log.e(TAG,"Lock2 running");                while(true){                    synchronized(DeadLock.obj2){                        Log.e(TAG, "Lock2 lock obj2");                        Thread.sleep(3000);                        synchronized(DeadLock.obj1){                            Log.e(TAG, "Lock2 lock obj1");                        }                    }                }            }catch(Exception e){                e.printStackTrace();            }        }    }}

可以看到,Lock1获取obj1,Lock2获取obj2,但是它们都没有办法再获取另外一个obj,因为它们都在等待对方先释放锁,这时就是死锁开发中一定要避免

线程间通信

public class Res {    String name;    String sex;    boolean flag=false;}

这里对同一个资源由不同的线程操作,必须用到Runnable类,wait、notify方法。由flag判断后决定是否wait,操作完成后notify

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Res r = new Res();        Input in = new Input(r);        Output out = new Output(r);        Thread t1 = new Thread(in);        Thread t2 = new Thread(out);        t1.start();        t2.start();    }    class Input implements Runnable {        private Res r ;        Input(Res r)        {            this.r = r;        }        public void run()        {            int x = 0;            while(true)            {                synchronized(r)                {                    if(r.flag)                        try{r.wait();}catch(Exception e){}                    if(x==0)                    {                        r.name="大强";                        r.sex="男";                    }                    else                    {                        r.name="小丽";                        r.sex = "女女女女女";                    }                    x = (x+1)%2;                    r.flag = true;                    r.notify();                }            }        }    }    class Output implements Runnable{        private Res r ;        Output(Res r)        {            this.r = r;        }        public void run()        {            while(true)            {                synchronized(r)                {                    if(!r.flag)                        try{r.wait();}catch(Exception e){}                    Log.e("mrpeng", "run: "+r.name+"...."+r.sex );//                    System.out.println(r.name+"...."+r.sex);                    r.flag = false;                    r.notify();                }            }        }    }}

也可用同步方法

public class Res {    private String name;    private String sex;    private boolean flag = false;    public synchronized void set(String name,String sex)    {        if(flag)            try{this.wait();}catch(Exception e){}        this.name = name;        this.sex = sex;        flag = true;        this.notify();    }    public synchronized void out()    {        if(!flag)            try{this.wait();}catch(Exception e){}        Log.e("mrpeng", "out: "+name+"........"+sex );        flag = false;        this.notify();    }}
public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Res r = new Res();        new Thread(new Input(r)).start();        new Thread(new Output(r)).start();    }    class Input implements Runnable {        private Res r;        Input(Res r) {            this.r = r;        }        public void run() {            int x = 0;            while (true) {                if (x == 0)                    r.set("小强", "man");                else                    r.set("小丽", "女女女女女");                x = (x + 1) % 2;            }        }    }    class Output implements Runnable {        private Res r;        Output(Res r) {            this.r = r;        }        public void run() {            while (true) {                r.out();            }        }    }}
0 0