繁体   English   中英

Java锁定(同步)全局变量

[英]Java lock (synchronize) global variable

我有一个密码

public class Exec {

    private String string = "";

    public void start() {
        MyThread t = new MyThread();
        MyThread2 t2 = new MyThread2();
        t.start();
        t2.start();
    }

    private class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {

                string = "1";

                System.out.println(string);
                try {
                    sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private class MyThread2 extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {

                string = "2";

                System.out.println(string);
                try {
                    sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

这没什么难的。 2个线程打印一个值。

输出:

1
2
1
2
1
...

问题我如何锁定全局变量(资源)? 输出:

1
1
1
1
...
2
2
2
2
...

在启动第二个线程之前(或在启动之后,但进入for循环之前),您可以调用t.join() ,它将阻塞直到完成t

简单的解决方案是将start()更改为run()因为您实际上不需要多个线程。

但是你可以使用这个

synchronized(Exec.class) {

要么

synchronized(System.out) {

作为共享的全局对象,也可以传递此类对象。

只需创建一个锁变量并锁定该变量即可。

public class Exec {

    private String string = "";
    private Object globalLock = new Object();  // The global lock  

    public void start() {
        MyThread t = new MyThread(globalLock);
        MyThread2 t2 = new MyThread2(globalLock);
        t.start();
        t2.start();
    }

    private class MyThread extends Thread {
        private Object lock;

        public MyThread(Object lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            synchronized(lock) {
                for (int i = 0; i < 10; i++) {
                    string = "1";
                    System.out.println(string);
                    try {
                        sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    private class MyThread2 extends Thread {
        private Object lock;

        public MyThread2(Object lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            synchronized(lock) {
                for (int i = 0; i < 10; i++) {
                    string = "2";
                    System.out.println(string);
                    try {
                        sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
class Exec{
private String string = "";
Object lock = new Object();
    public void start() {
        MyThread t = new MyThread();
        MyThread2 t2 = new MyThread2();
        t.start();
        t2.start();
    }

    public static void main(String[] args) {
        new MyServer().start();
    }

    private class MyThread extends Thread {
        @Override
        public void run() {
            synchronized (lock) {


            for (int i = 0; i < 10; i++) {

                string = "1";

                System.out.println(string);
                try {
                    sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }
        }


    }

    private class MyThread2 extends Thread {
        @Override
        public void run() {
            synchronized (lock) {


            for (int i = 0; i < 10; i++) {

                string = "2";

                System.out.println(string);
                try {
                    sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }
        }
    }
}

虽然当您要顺序执行代码块时使用多线程没有意义,但是仍然可以通过多种方式解决此问题。 您可以使用锁定机制(内部,外部,任何Lock接口实现等),同步器等。IMO最简单的方法是使用volatile变量:

public class Exec{
    private volatile boolean lock = false;

    private String string = "";

    public void start() {
        MyThread t = new MyThread();
        MyThread2 t2 = new MyThread2();
        lockResource();
        t.start();
        t2.start();
    }

    void lockResource() {
        lock = true;
    }

    void releaseResource() {
        lock = false;
    }

    private class MyThread extends Thread {
        @Override
        public void run() {
            while (!lock) ;
            for (int i = 0; i < 10; i++) {
                string = "1";

                System.out.println(string);
                try {
                    sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            releaseResource();
        }
    }

    private class MyThread2 extends Thread {
        @Override
        public void run() {
            while (lock) ;
            for (int i = 0; i < 10; i++) {
                string = "2";
                System.out.println(string);
                try {
                    sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

由于布尔变量lock为false,因此第一个线程将继续打印,而其他线程具有while循环以保持等待状态。 一旦第一个线程完成,它将布尔值设置为true,并且由于lock是易失的,其他线程也将看到此更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM