问题描述
我想试一下synchronized关键字是不是有效?所以写了一个很简单的类,但是就是不能调到数字按序排列。不知道错在哪里了。数字序列类:package com.testthread;public class UnsafeSequence {private int value = 0;public synchronized int getValue(){value = value+1;return value;}}线程类package com.testthread;public class TestThread extends Thread {private UnsafeSequence us;public TestThread(UnsafeSequence us, String threadname) {super(threadname);this.us = us;}@Overridepublic void run() {String classname = this.getClass().getSimpleName();String threadname = currentThread().getName();for (int i = 0; i < 5; i++) {System.out.println(classname + "[" + threadname + "]:"+ us.getValue());}}}Main类package com.testthread;public class MainClass {public static void main(String[] args) throws InterruptedException {System.out.println("Main started");UnsafeSequence us = new UnsafeSequence();TestThread at = new TestThread(us,"at");TestThread bt = new TestThread(us,"bt");at.start();bt.start();System.out.println("Main ended");}}可是结果是:Main startedMain endedTestThread[bt]:2TestThread[bt]:3TestThread[at]:1TestThread[at]:5TestThread[at]:6TestThread[at]:7TestThread[at]:8TestThread[bt]:4TestThread[bt]:9TestThread[bt]:10我想让数字按序排列,可是数字没有按序排列,请问哪里写错了,谢谢 问题补充:我的机器是多核cpu,会不会和多核cpu有关呢?
解决方案
你真要输出1-10的话,应该在UnsafeSequence.getValue里面输出value的值,肯定就是1-10了,因为System.out.println的执行和getValue的执行是两个方法的调用,getValue方法调用返回以后,不一定它就马上执行了System.out.println,因为这个时候可能又转到别的线程执行去了,加synchronized唯一能保证的是,getValue无论多少个线程同时调用,他一定会序列化执行,也就是在这里输出value的值,一定是递增的。
解决方案二:
你的问题是这样的 楼上的已经说的很清楚了 我在简单说一下 若多个线程 同时跑到 System.out.println(classname + "[" + threadname + "]:" + us.getValue()); 这句话 这时 方法getValue()会有锁 所以只能一个线程进去 但是 并不能保证谁先输出结果 所以顺序会乱修改: 1.去掉 getValue()方法前的 Synchronized 2.synchronized (us) {System.out.println(classname + "[" + threadname + "]:"+ us.getValue()); }(在输出那句话上 用synchronized锁定 这样保证 一个一个的进入)
解决方案三:
public class UnsafeSequence {private AtomicInteger value = new AtomicInteger(0);public int getValue() {return value.incrementAndGet();}public static void main(String[] args) {System.out.println("Main started");UnsafeSequence us = new UnsafeSequence();TestThread at = new TestThread(us, "at");TestThread bt = new TestThread(us, "bt");at.start();bt.start();System.out.println("Main ended");}}class TestThread extends Thread {private UnsafeSequence us;public TestThread(UnsafeSequence us, String threadname) {super(threadname);this.us = us;}@Overridepublic void run() {String classname = this.getClass().getSimpleName();String threadname = currentThread().getName();for (int i = 0; i < 10; i++) {synchronized (us) {System.out.println(classname + "[" + threadname + "]:" + us.getValue());}}}}
解决方案四:
概念混淆了吧,synchronized只能保证同一时刻共享资源被唯一访问,可没说能排序啊