0 0

我是新人,关于Java线程的问题,很简单的例子,可是我就是调不出来,不知道哪里错了5

我想试一下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;
	}

	@Override
	public 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 started
Main ended
TestThread[bt]:2
TestThread[bt]:3
TestThread[at]:1
TestThread[at]:5
TestThread[at]:6
TestThread[at]:7
TestThread[at]:8
TestThread[bt]:4
TestThread[bt]:9
TestThread[bt]:10


我想让数字按序排列,可是数字没有按序排列,请问哪里写错了,谢谢

问题补充:我的机器是多核cpu,会不会和多核cpu有关呢?
2013年1月29日 22:20

4个答案 按时间排序 按投票排序

0 0

采纳的答案

你真要输出1-10的话,应该在UnsafeSequence.getValue里面输出value的值,肯定就是1-10了,因为System.out.println的执行和getValue的执行是两个方法的调用,getValue方法调用返回以后,不一定它就马上执行了System.out.println,因为这个时候可能又转到别的线程执行去了,加synchronized唯一能保证的是,getValue无论多少个线程同时调用,他一定会序列化执行,也就是在这里输出value的值,一定是递增的。

2013年1月29日 23:55
0 0

你的问题是这样的  楼上的已经说的很清楚了   我在简单说一下 
若多个线程 同时跑到 
    System.out.println(classname + "[" + threadname + "]:" 
                    + us.getValue()); 
这句话 这时 方法getValue()会有锁  所以只能一个线程进去 但是 并不能保证谁先输出结果  所以顺序会乱

修改:
   1.去掉 getValue()方法前的 Synchronized
   2.synchronized (us) {
System.out.println(classname + "[" + threadname + "]:"
+ us.getValue());
     }
(在输出那句话上 用synchronized锁定  这样保证 一个一个的进入)

2013年1月30日 11:44
0 0

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;
	}

	@Override
	public 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());
			}
			
		}
	}
}

2013年1月30日 11:38
0 0

概念混淆了吧,synchronized只能保证同一时刻共享资源被唯一访问,可没说能排序啊

2013年1月30日 10:22

相关推荐

    javajd100_java基础_100例子_

    "javajd100_java基础_100例子_" 这个压缩包文件显然为初学者提供了学习Java基础知识的绝佳资源,通过100个不同的实例帮助理解和掌握Java编程。 首先,让我们了解一下Java的基础知识。Java是一种面向对象的编程语言...

    浅谈java中的几种随机数

    然而,这种方法的一个潜在问题是它并不总是能够提供均匀分布的结果,特别是在涉及到四舍五入时,如上述的`Math.round()`例子。 为了更精细地控制随机数的生成,可以使用`java.util.Random`类。这个类提供了多种生成...

    java经典编程300例

    《Java经典编程300例》是一份专为初学者设计的资源,旨在帮助那些已经掌握J2SE基础知识,但尚缺乏实践经验的开发者快速提升实战技能。这份资源包含了一系列实际可运行的Java代码示例,涵盖了Java开发中的常用场景和...

    Java开发实战经典--李兴华--完整书签

    《Java开发实战经典》是由李兴华编著的一本针对初学者的Java编程教材,它以其详尽的基础知识和易懂的讲解方式深受广大读者喜爱。这本书旨在为那些对Java编程感兴趣但缺乏经验的新手提供一个系统的学习路径,帮助他们...

    L6多线程&异步编程

    "多线程实现打字练习"可能是一个利用多线程来提高用户交互体验的例子,其中,一个线程负责接收用户输入,另一个线程处理输入并显示结果。这种设计可以确保即使在处理复杂计算时,用户界面仍然保持流畅。 ...

    Head First Java (中文版)

    《Head First Java》是针对初学者的一本极富创新性的Java编程教材,中文版的推出使得更多的中国读者能够轻松入门Java编程世界。本书以其独特的视觉风格、丰富的图表和轻松幽默的语言,深受全球程序员喜爱,被誉为...

    Thinking in Java

    《Thinking in Java》是一本备受推崇的Java编程教程,作者是Bruce Eckel,他在书中以其独特的教学方式,引领读者逐步深入理解Java语言的核心概念和技术。这本书不仅适合初学者,也适合有一定经验的程序员,帮助他们...

    面试的技巧

    在IT行业中,面试是每个程序员职业生涯中不可或缺的一部分。无论你是初入职场的新人,还是希望晋升加薪的老手,掌握面试技巧都能显著提高你的成功概率。以下是一些关键的面试技巧,尤其是对于Java程序员来说,这些...

    Android示例大全(从培训到工作所有的例子)

    学习Android开发不仅需要掌握Java或Kotlin语言基础,还需要理解Android SDK、Activity生命周期、Intent机制、UI设计、数据存储、网络通信、多线程、权限管理等众多知识。 在《Android示例大全》中,你可以找到以下...

Global site tag (gtag.js) - Google Analytics