与单例对象或字符串同步的线程连接

时间:2018-08-15 04:08:11

标签: java multithreading thread-safety

System.out.println(“嘿,明白了......”);从未在我的程序中执行

由于同步关键字,我可以理解它的含义,但是实际上发生了什么。

从CFG类调用的TestJoin类,问题出在此类中

$('#createModal').modal('show');

只需创建另一个线程,即可从TestJoin类调用它

 class TestJoin implements Runnable{

    public String x;

    TestJoin(String x){
        this.x= x;

    }

    public void testJoin() {
        System.out.println("b4"+x);
        synchronized(x) {
            System.out.println(x);
            ThreadJoining t1 = new ThreadJoining("2");

            // thread t1 starts
            t1.start();
            System.out.println("you fool");
            try{
                System.out.println(
                    "Current Thread: "+ 
                    Thread.currentThread().getName()
                );
                t1.join();
               //never this line is executed
               System.out.println("hey got it....");
            }catch(Exception ex){
                System.out.println(
                       "Exception has " +
                       "been caught" + ex
                );
            }
        }
    }

    @Override
    public void run() {
            testJoin();
    }
}

主类执行从这里开始

class ThreadJoining extends Thread{
        String c;
        ThreadJoining(String co){
            c=co;
        }
        @Override
        public void run()
        {
            synchronized(c) {
                for (int i = 0; i < 2; i++){
                try{
                    Thread.sleep(500);
                    System.out.println(
                             "Current Thread: " +
                             Thread.currentThread().getName()
                    );
                }catch(Exception ex){
                    System.out.println(
                                "Exception has" +
                                " been caught" + ex
                    );
                }
                System.out.println(i);
            }
        }
    }
}

以上执行的输出

public class GFG{
    public static void main (String[] args){

        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                System.out.println("Bye Bye");
            }
        });
        new Thread(new TestJoin("1")).start();
        new Thread(new TestJoin("1")).start();
        new Thread(new TestJoin("2")).start();
        new Thread(new TestJoin("3")).start();

     }
}

第二次修改:

仅当我与字符串或单例对象同步时,才出现上述问题, 如果我使用一个新对象完美的文件

示例,具有正常的对象同步

b41
1
b43
3
b42
2
b41
you fool
Current Thread: Thread-4
you fool
Current Thread: Thread-1
you fool
Current Thread: Thread-3

输出

public class GFG{
        public static void main (String[] args){

            Runtime.getRuntime().addShutdownHook(new Thread() {
                public void run() {
                    System.out.println("Bye Bye");
                }
            });
           Sample s =  new Sample();
           new Thread(new TestJoin(s)).start();
           new Thread(new TestJoin(s)).start();
           new Thread(new TestJoin(new Sample())).start();
           new Thread(new TestJoin(new Sample())).start();

        }
    }

public class TestJoin implements Runnable{

    public Sample x;
    TestJoin(Sample x){
        this.x= x;

    }

    public void testJoin() {
        System.out.println("b4"+x);
        synchronized(x) {
            System.out.println(x);
    ThreadJoining t1 = new ThreadJoining("2");

    // thread t1 starts
    t1.start();
    System.out.println("you fool");
    try
    {
        System.out.println("Current Thread: "
              + Thread.currentThread().getName());
        t1.join();
        System.out.println("hey got it....");
    }

    catch(Exception ex)
    {
        System.out.println("Exception has " +
                            "been caught" + ex);
    }
        }
    }

    @Override
    public void run() {
            testJoin();
    }
}

class ThreadJoining extends Thread{
    String c;
    ThreadJoining(String co){
        c=co;
    }

    @Override
    public void run(){
        synchronized(c) {
            for (int i = 0; i < 2; i++){
                try{
                    Thread.sleep(500);
                    System.out.println(
                        "Current Thread: " +
                        Thread.currentThread().getName()
                    );
                }catch(Exception ex){
                    System.out.println(
                        "Exception has" +
                        " been caught" + ex
                    );
                }
                System.out.println(i);
            }
        }
    }
}

public class Sample {

}

1 个答案:

答案 0 :(得分:3)

这是因为String常量是内部变量,因此在"2"ThreadJoining中的TestJoin上进行同步时,实际上是在锁定同一对象。

new TestJoin("2")锁定"2"然后等待new ThreadJoining("2")完成时,这将导致死锁(这永远不会发生,因为它无法获得{{1 }}。