线程一1.0 线程 synchronized的缺陷

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/insis_mo/article/details/88555413

1一 synchronized的缺陷

synchronized关键字提供了一种排他试的数据同步机制,某个线程在获取 monitor lock的时候可能会被阻塞,而这种阻塞有两个很明显的缺陷,第一无法控制阻塞时长,第二:阻塞不可中断,如下:

public class SynchnizedDefed {
    public  synchronized void syncMethod(){
        try {
            System.out.println(Thread.currentThread().getName()+"来了");
            TimeUnit.HOURS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        SynchnizedDefed synchnizedDefed=new SynchnizedDefed();
        
        Thread t1=new Thread(synchnizedDefed::syncMethod,"t1");
        t1.start();
        try {
            TimeUnit.MILLISECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        Thread t2=new Thread(synchnizedDefed::syncMethod,"t2");
        t2.start();
    }
}

上面代码中有一个同步方法syncMethod,这里启动了两个线程分别调用该方法,在该方法中线程会休眠一个小时的时间,为了确保T1线程能够最先进入同步方法,在T1线程启动后主线程休眠了两毫秒,T2线程启动执行syncMethod方法时、会进入阻塞,T2什么时候能够获得syncMethod的执行完全取决于T1何时对其释放,如果T2最多1分钟获得执行权,否则就放弃,很显然这种方式是做不到的,也就是说的阻塞时长无法控制。

第二个缺陷是T2若因争抢某个monitor的锁而进入阻塞状态,那么他是无法中断的,虽然可以设置T2线程的int标识,但是synchronized阻塞不像sleep和wait 方法一样能够捕获到中断信号,下面方法试图打断T2线程,看看:

public class SynchnizedDefed {
    public  synchronized void syncMethod(){
        try {
            System.out.println(Thread.currentThread().getName()+"来了");
            TimeUnit.HOURS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        SynchnizedDefed synchnizedDefed=new SynchnizedDefed();
        
        Thread t1=new Thread(synchnizedDefed::syncMethod,"t1");
        t1.start();
            TimeUnit.MILLISECONDS.sleep(2);
        
        Thread t2=new Thread(synchnizedDefed::syncMethod,"t2");
        t2.start();
            TimeUnit.MILLISECONDS.sleep(2);
        
        t2.interrupt();
        System.out.println(t2.isInterrupted());
        System.out.println(t2.getState());
    }
}

结果一定很失望,也证明了被synchronized同步的线程不可被中断,

猜你喜欢

转载自blog.csdn.net/insis_mo/article/details/88555413