-
我是新人,关于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个答案 按时间排序 按投票排序
-
采纳的答案
你真要输出1-10的话,应该在UnsafeSequence.getValue里面输出value的值,肯定就是1-10了,因为System.out.println的执行和getValue的执行是两个方法的调用,getValue方法调用返回以后,不一定它就马上执行了System.out.println,因为这个时候可能又转到别的线程执行去了,加synchronized唯一能保证的是,getValue无论多少个线程同时调用,他一定会序列化执行,也就是在这里输出value的值,一定是递增的。
2013年1月29日 23:55
-
你的问题是这样的 楼上的已经说的很清楚了 我在简单说一下
若多个线程 同时跑到
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
-
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
相关推荐
"javajd100_java基础_100例子_" 这个压缩包文件显然为初学者提供了学习Java基础知识的绝佳资源,通过100个不同的实例帮助理解和掌握Java编程。 首先,让我们了解一下Java的基础知识。Java是一种面向对象的编程语言...
然而,这种方法的一个潜在问题是它并不总是能够提供均匀分布的结果,特别是在涉及到四舍五入时,如上述的`Math.round()`例子。 为了更精细地控制随机数的生成,可以使用`java.util.Random`类。这个类提供了多种生成...
《Java经典编程300例》是一份专为初学者设计的资源,旨在帮助那些已经掌握J2SE基础知识,但尚缺乏实践经验的开发者快速提升实战技能。这份资源包含了一系列实际可运行的Java代码示例,涵盖了Java开发中的常用场景和...
《Java开发实战经典》是由李兴华编著的一本针对初学者的Java编程教材,它以其详尽的基础知识和易懂的讲解方式深受广大读者喜爱。这本书旨在为那些对Java编程感兴趣但缺乏经验的新手提供一个系统的学习路径,帮助他们...
"多线程实现打字练习"可能是一个利用多线程来提高用户交互体验的例子,其中,一个线程负责接收用户输入,另一个线程处理输入并显示结果。这种设计可以确保即使在处理复杂计算时,用户界面仍然保持流畅。 ...
《Head First Java》是针对初学者的一本极富创新性的Java编程教材,中文版的推出使得更多的中国读者能够轻松入门Java编程世界。本书以其独特的视觉风格、丰富的图表和轻松幽默的语言,深受全球程序员喜爱,被誉为...
《Thinking in Java》是一本备受推崇的Java编程教程,作者是Bruce Eckel,他在书中以其独特的教学方式,引领读者逐步深入理解Java语言的核心概念和技术。这本书不仅适合初学者,也适合有一定经验的程序员,帮助他们...
在IT行业中,面试是每个程序员职业生涯中不可或缺的一部分。无论你是初入职场的新人,还是希望晋升加薪的老手,掌握面试技巧都能显著提高你的成功概率。以下是一些关键的面试技巧,尤其是对于Java程序员来说,这些...
学习Android开发不仅需要掌握Java或Kotlin语言基础,还需要理解Android SDK、Activity生命周期、Intent机制、UI设计、数据存储、网络通信、多线程、权限管理等众多知识。 在《Android示例大全》中,你可以找到以下...