多线程总结持续更新

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)持续更新

C#中级-常用多线程操作(持续更新)

线程学习知识点总结

Java面试题⭐多线程篇⭐(万字总结,带答案,面试官问烂,跳槽必备,建议收藏)

Java面试题⭐多线程篇⭐(万字总结,带答案,面试官问烂,跳槽必备,建议收藏)

Java面试题⭐多线程篇⭐(万字总结,带答案,面试官问烂,跳槽必备,建议收藏)