关于线程&锁
来源:互联网 发布: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(); } } }}
- 关于线程&锁
- 关于线程锁的学习
- 关于线程锁的相关
- 关于线程
- 关于线程
- 关于线程
- 关于线程
- 关于线程
- 关于线程
- 关于线程
- 关于线程
- 关于线程
- 关于 线程
- 关于线程
- 关于线程
- 关于线程
- 关于线程
- 关于线程
- 简单实现消息提示(小红点)
- JQuery简单切换
- 图书管理系统设计
- java+mysql实现保存图片到数据库,以及读取数据库存储的图片
- 点击连着两次回车键退出程序
- 关于线程&锁
- 常用存储引擎对mysql性能的影响
- 2017团队天梯赛决赛题选做
- git教程(一)
- 以CSDN为例解释尼尔森十大交互原则
- 解决IntelliJ IDEA中getResourceAsStream取得null问题
- Glide的用法
- mysql executeBatch()方法
- 语义分割(semantic segmentation) 常用神经网络介绍对比-FCN SegNet U-net DeconvNet