欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java多线程-同步和死锁

程序员文章站 2022-03-10 16:03:20
...

多线程:一个进程中开启了不止一个线程,高速CPU时间片的切换调度线程
1、作用:
①可以充分调用系统资源,提高CPU的使用率,执行某些耗时操作;
②可以实现异步调用(主要功能),提高程序的工作效率。
2、问题:
①当线程数量很大时,CPU需要切换调度,会影响性能;
②线程越多,需要的内存空间越大;
③可能会出现线程安全或者死锁等问题。
3、多线程并行和并发的区别:
· 并行:多个处理器或者多核处理器同使执行多个不同的任务;
· 并发:一个处理器处理多个任务。
(多个线程操作共享数据,可能会出现线程安全问题,使用synchronized保证线程同步)
4、线程的同步:以某种方式来确保资源在某一时刻仅被一个线程占用
*同步块和同步方法:

// Synchronized同步方法,当有一个线程访问该方法时,就会拿到同步锁将方法锁住,其他线程再来访问时需要等待上一个线程执行完成
    private static /*synchronized*/ void test() {
// 给test方法加synchronized(同步锁),同步方法的同步锁是类的同步锁
    System.out.println(Thread.currentThread().getName());

        synchronized (ThreadDemo.class) { 
        // 同步块:当某一线程进入同步块后,
        // 其他线程都不能进入,要等待该线程执行完成
            for (int i = 0; i < 100; i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }       System.out.println(Thread.currentThread().getName());
            }
        }
    }

5、线程的死锁:如果你已有一个锁并试图获取另一个锁时,就有死锁的危险.
线程1锁住了对象A的监视器,等待对象B的监视器,线程2锁住了对象B的监视器,等待对象A的监视器,就造成了死锁。
java多线程-同步和死锁
**演示死锁,代码如下:创建两个类,相互调用

public class ThreadDemo {
    public static void main(String[] args) {
        final A a = new A(); //类的实例:A,B默认都是final类型的,因为在内部类中访问
        final B b = new B();
        //创建2个线程
        Thread th1 = new Thread(new Runnable() {
            @Override
            public void run() {
                a.a1(b); //线程1调用A类的a1方法,参数是B类的实例b
            }
        }); 
        Thread th2 = new Thread(new Runnable() {
            @Override
            public void run() {
                b.b1(a); //线程2调用B类的b1方法,参数是A类的实例a
            }
        });
        th1.setName("线程1");
        th2.setName("线程2");
        th1.start();
        th2.start();
    }
}

class A{  //给A类的两个方法都加上锁synchronized,演示死锁状态
    public synchronized void a1(B b){ //在A类中接收B类的实例
    System.out.println(Thread.currentThread().getName()+"正在调用A类的a1方法!"); //得到当前访问该方法的线程名称
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    System.out.println(Thread.currentThread().getName()+"正在A类的a1方法中调用B类的b2方法!");
        b.b2();
    }
    public synchronized void a2(){
        System.out.println("A类的a2方法");
    }
}

class B{
    public synchronized void b1(A a){ //在B类中接收A类的实例
    System.out.println(Thread.currentThread().getName()+"正在调用A类的a1方法!");
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    System.out.println(Thread.currentThread().getName()+"正在B类的b1方法中调用A类的a2方法!");
        a.a2();
    }
    public synchronized void b2(){
        System.out.println("B类的b2方法");
    }
}