java里线程同步方法一:同步线程块

有时候使用多进程时会导致进程不同步,这样会导致运行结果的错误。
看下面的代码:

class ThreadDemo1 {
    public static void main(String[] args) {
        TestThread tt = new TestThread();
        new Thread(tt).start();
        new Thread(tt).start();
        new Thread(tt).start();
        new Thread(tt).start();

    }

}

class TestThread implements Runnable {
    int tickets = 100;

    public void run() {
        while (true) {
            if (tickets > 0) {
                try {
                    Thread.sleep(10);
                } catch (Exception e) {
                }
                System.out.println(Thread.currentThread().getName()
                        + " is saling ticket " + tickets--);
            }
        }
    }
}

运行结果:
java里线程同步方法一:同步线程块_第1张图片

从运行结果可以看出最后输出了负数,因为当一个线程判断了tickets==1时(大于零),这时它睡眠了10毫秒,这时其他进程会没有判断就输出了票数,再将tickets–,这样就会导致输入负数。
要让它不会出错就要用到进程同步块synchronized。
修改代码如下:

class ThreadDemo1 {
    public static void main(String[] args) {
        TestThread tt = new TestThread();
        new Thread(tt).start();
        new Thread(tt).start();
        new Thread(tt).start();
        new Thread(tt).start();

    }
}

class TestThread implements Runnable {
    int tickets = 100;
    String str = new String("");

    public void run() {
        while (true) {
            synchronized (str) {
                if (tickets > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (Exception e) {
                    }
                    System.out.println(Thread.currentThread().getName()
                            + " is saling ticket " + tickets--);
                }
            }
        }
    }
}

运行结果:
java里线程同步方法一:同步线程块_第2张图片

ynchronized的原理可以这样理解:当程序进入synchronized代码块时会检查对象(这里的对象是str,假设标志位为1运行,为0时阻塞)的标志位,如果为1时将标志位置0之后再运行,当标志位为0时阻塞等标志位为1。但synchronized同步代码块会影响运行速度。

:String str = new String(“”);语句不能放在run方法里,因为每个线程运行都有自己的run方法,那么就会创建四个str对象,初始标志位都为1.

你可能感兴趣的:(java,线程)