【Java多线程学习笔记】suspend及resume方法的缺点——独占

“在使用suspend与resume方法时,如果使用不当,极易造成公共的同步对象独占,使得其他线程无法访问公共同步对象”

【独占原因&代码分析】

1、在同步方法printString() 中线程a被暂停,锁无法释放,其他线程无法访问printString() 

package suspend_resume_deal_lock;

/**
 * @author chengsw
 * @create 2019-06-30 15:50
 */
public class SynchronizedObject {

    synchronized public void printString() {
        System.out.println("begin");
        if (Thread.currentThread().getName().equals("a")) {
            System.out.println("a线程永远suspend");
            Thread.currentThread().suspend();
        }
        System.out.println("end");
    }
}
package suspend_resume_deal_lock;

/**
 * @author chengsw
 * @create 2019-06-30 15:59
 */
public class Run {

    public static void main(String[] args) {
        try {
            final SynchronizedObject so = new SynchronizedObject();
            Thread th1 = new Thread() {
                @Override
                public void run() {
                    so.printString();
                }
            };
            th1.setName("a");
            th1.start();
            Thread.sleep(2000);
            Thread th2 = new Thread() {
                @Override
                public void run() {
                    System.out.println("thread2线程启动了,但是不能进入println方法,因为线程已经被a锁定且暂停");
                    System.out.println("因为printString()方法被a线程锁定并且永远suspend暂停了!");
                    so.printString();
                }
            };
            th2.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

运行结果

2、println()造成的锁不能释放

package suspend_resume_LockStop;

/**
 * @author chengsw
 * @create 2019-06-30 16:12
 */
public class MyThread extends Thread {

    private long i = 0;

    @Override
    public void run() {
        while(true) {
            i++;
            System.out.println(i);
        }
    }
}
package suspend_resume_LockStop;

/**
 * @author chengsw
 * @create 2019-06-30 16:18
 */
public class Run {

    public static void main(String[] args) {
        try {
            MyThread th = new MyThread();
            th.start();
            Thread.sleep(1_000);
            th.suspend();
            System.out.println("main end~~");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

并没有打印main end~~

由上面源码可知,当程序运行到println()内部暂停线程时,同步锁无法释放。

当前PrintStream对象的println()方法在同步代码块内暂停,则println()的锁一直无法释放,因此一直打印数据,但无法执行main方法中的println("main end~~")

发布了32 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chengsw1993/article/details/94332073