多线程总结持续更新
Posted gxyandwmm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程总结持续更新相关的知识,希望对你有一定的参考价值。
1、interrupt()方法:
interrupt()只是改变中断状态而已. interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,给受阻塞的线程抛出一个中断信号,这样受阻线程就得以退出阻塞的状态。
如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。
public class InterruptWait extends Thread { public static Object lock = new Object(); @Override public void run() { System.out.println("start"); synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().isInterrupted()); Thread.currentThread().interrupt(); // set interrupt flag again System.out.println(Thread.currentThread().isInterrupted()); e.printStackTrace(); } } } public static void main(String[] args) { Thread thread = new InterruptWait(); thread.start(); try { sleep(2000); } catch (InterruptedException e) { } thread.interrupt(); } }
在这种方式下,如果使用 wait 方法处于等待中的线程,被另一个线程使用中断唤醒,于是抛出 InterruptedException,同时,
中断标志清除,这时候我们通常会在捕获该异常的地方重新设置中断,以便后续的逻辑通过检查中断状态来了解该线程是如何结束的 。
2、wait 和 notify的使用
先看一个因为多线程导致 数据数据读取有错误的例子:
写着:
public class WritePerson implements Runnable{ private Person person = null; WritePerson(Person p) { this.person = p; } private boolean flag = true; @Override public void run() { while(true) { if( flag == true) { person.setName("Jack"); person.setSex(‘男‘); flag = false; }else { person.setName("Lily"); person.setSex(‘女‘); flag = true; } } } }
读者:
public class ReadPerson implements Runnable{ private Person person = null; ReadPerson(Person p) { this.person = p; } @Override public void run() { while(true) { System.out.println("name---->: " + person.getName() + " sex----->: " + person.getSex()); } } }
测试:
public static void main(String[] args) { Person person = new Person(); WritePerson wp = new WritePerson(person); ReadPerson rp = new ReadPerson(person); Thread t1 = new Thread(wp); Thread t2 = new Thread(rp); t1.start(); t2.start(); }
测试结果:
name---->: Lily sex----->: 女 name---->: Jack sex----->: 男 name---->: Lily sex----->: 男 name---->: Lily sex----->: 女 name---->: Jack sex----->: 女 name---->: Lily sex----->: 女 name---->: Lily sex----->: 男 name---->: Jack sex----->: 男 name---->: Jack sex----->: 男 name---->: Jack sex----->: 女 name---->: Lily sex----->: 女 name---->: Jack sex----->: 女 name---->: Lily sex----->: 女 name---->: Lily sex----->: 男 name---->: Lily sex----->: 女 name---->: Jack sex----->: 男 name---->: Lily sex----->: 男 name---->: Lily sex----->: 男 name---->: Lily sex----->: 男 name---->: Lily sex----->: 男 name---->: Jack sex----->: 女
可以看到数据中存在读取错误问题;导致问题的根因是读者和写着没有实现同步;
下面进行使用wait 和 notify 实现同步:
读者:
public class ReadPerson implements Runnable{ private Person person = null; ReadPerson(Person p) { this.person = p; } @Override public void run() { synchronized (person) { while(person.getFlag() == true) { try { person.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("name---->: " + person.getName() + " sex----->: " + person.getSex()); person.setFlag(true); person.notify(); } } }
写者;
public class WritePerson implements Runnable{ private Person person = null; WritePerson(Person p) { this.person = p; } private boolean flag = true; private boolean flag2 = true; @Override public void run() { synchronized (person) { while(person.getFlag() == false) { try { person.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if( flag == true) { person.setName("Jack"); person.setSex(‘男‘); flag = false; }else { person.setName("Lily"); person.setSex(‘女‘); flag = true; } person.notify(); person.setFlag(false); } } }
执行;
public static void main(String[] args) { Person person = new Person(); person.setFlag(true); WritePerson wp = new WritePerson(person); ReadPerson rp = new ReadPerson(person); Thread t1 = new Thread(wp); Thread t2 = new Thread(rp); Thread t3 = new Thread(wp); Thread t4 = new Thread(rp); Thread t5 = new Thread(wp); Thread t6 = new Thread(rp); Thread t7 = new Thread(wp); Thread t8 = new Thread(rp); Thread t9 = new Thread(wp); Thread t10 = new Thread(rp); t1.start(); t3.start(); t5.start(); t2.start(); t4.start(); t6.start(); t7.start(); t8.start(); t9.start(); t10.start(); }
结果:
name---->: Jack sex----->: 男 name---->: Lily sex----->: 女 name---->: Jack sex----->: 男 name---->: Lily sex----->: 女 name---->: Jack sex----->: 男
将同步Synchronized替换为显示的Lock操作;将Object中的wait,notify,notifyAll替换为Condition对象,该对象可以通过Lock锁进行获取。
读者:
public class ReadPerson implements Runnable{ private Lock lock = null; Person person = null; private boolean flag = true; private Condition condition_pro = null; //condition绑定Lock private Condition condition_con = null; //1个lock可以绑定多个condition ReadPerson(Lock lock, Person person, Condition condition_pro, Condition condition_con) { this.lock = lock; this.person = person; this.condition_pro = condition_pro; this.condition_con = condition_con; } @Override public void run() { lock.lock(); while(person.getFlag() == true) { try { condition_con.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("name---->: " + person.getName() + " sex----->: " + person.getSex()); person.setFlag(true); condition_pro.signal(); lock.unlock(); } }
写者:
public class WritePerson implements Runnable{ private Lock lock = null; Person person = null; private boolean flag = true; private Condition condition_pro = null; //condition绑定Lock private Condition condition_con = null; //1个lock可以绑定多个condition WritePerson(Lock lock, Person person, Condition condition_pro, Condition condition_con) { this.lock = lock; this.person = person; this.condition_pro = condition_pro; this.condition_con = condition_con; } @Override public void run() { lock.lock(); while(person.getFlag() == false) { try { condition_pro.await(); } catch (InterruptedException e) { e.printStackTrace(); } } if( flag == true) { person.setName("Jack"); person.setSex(‘男‘); flag = false; }else { person.setName("Lily"); person.setSex(‘女‘); flag = true; } condition_con.signal(); person.setFlag(false); lock.unlock(); }
测试:
public static void main(String[] args) { Person person = new Person(true); Lock lock = new ReentrantLock(); Condition condition_pro = lock.newCondition(); //condition绑定Lock Condition condition_con = lock.newCondition(); //1个lock可以绑定多个condition System.out.println(condition_pro); System.out.println(condition_con); WritePerson wp = new WritePerson(lock, person, condition_pro, condition_con); ReadPerson rp = new ReadPerson(lock, person, condition_pro, condition_con); Thread t1 = new Thread(wp); Thread t2 = new Thread(rp); Thread t3 = new Thread(wp); Thread t4 = new Thread(rp); Thread t5 = new Thread(wp); Thread t6 = new Thread(rp); Thread t7 = new Thread(wp); Thread t8 = new Thread(rp); Thread t9 = new Thread(wp); Thread t10 = new Thread(rp); t1.start(); t3.start(); t5.start(); t2.start(); t4.start(); t6.start(); t7.start(); t8.start(); t9.start(); t10.start(); }
输出:
name---->: Jack sex----->: 男 name---->: Lily sex----->: 女 name---->: Jack sex----->: 男 name---->: Lily sex----->: 女 name---->: Jack sex----->: 男
以上是关于多线程总结持续更新的主要内容,如果未能解决你的问题,请参考以下文章
2022年4月最新面经答案总结(Java基础数据库JVM计网计操集合多线程Spring)持续更新
Java面试题⭐多线程篇⭐(万字总结,带答案,面试官问烂,跳槽必备,建议收藏)