java有没有大神帮我改一下java程序改错,为什么我的线程加不进去

谁帮我一下修改一个简单的java程序?关于多线程的弹球程序。主要问题:编译运行以后就是不能出现小球._百度知道
谁帮我一下修改一个简单的java程序?关于多线程的弹球程序。主要问题:编译运行以后就是不能出现小球.
编写程序,该程序通过一个发射按钮可以发射一个弹球,该球遇到边界时会自动弹回,在移动固定次数后,该球停止运动。要求每次点击发射按钮都会发射一个弹球,如果点击多次,则多个弹球同时运动。该程序通过另一个结束可以结束程序的运行。
我有更好的答案
此种情况不应该使用多线程,要是开发像雷电一样射击类的游戏,岂不是线程多如牛毛?
采纳率:28%
确实很简单啊...
呵呵呵我也是刚学
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。一个程序里,是不是只应该只有一个线程池? - ITeye问答
我现在用Netty+spring+Mybatis做了一个长连接服务端,内部有多处要执行短暂的并发任务,还需要做定时任务,我需要用到ExecutorService和ScheduledExecutorService两者,但是这两者貌似一个就是一个线程池,而且我试用线程的地方有多处,我有两个问题,一能否把他们统一成一个线程池,二是我是不是必须把这个线程池作为一个全局变量(静态)才能保证到处被调用?
又看了一下API
Executors虽然实现线程池,但如果提交线程过多内存肯定会吃内存。利用底层ThreadPoolExecutor来实现,当队列满的时候自动阻塞。
http://heipark.iteye.com/blog/1393847这个博客讲了原理。
http://blog.163.com/nihaonihao/blog/static//这个是spring中配置。
问题的关键不在于使用多少个线程池, 而在于实际有多少个线程.
虽然一般线程池都会只开一个.
但是你看netty源码, 应该就知道, 其他他使用好几个线程池的.
java代码的话就要设计全局。spring中通过配置ThreadPoolTaskExecutor也可以实现线程池,对应java中ThreadPoolExecutor,java中所有线程池底层都是ThreadPoolExecutor实现的。但手动实现ThreadPoolExecutor比较麻烦,Executors中已经对这些线程接口做了实现,帮助文档建议使用些类。
ScheduledExecutorService& 继承ExecutorService 。都是接口啊、&&
Executors.newScheduledThreadPool& 这个就是线程池啊。&
ExecutorService es=Executors.newScheduledThreadPool 你可以用这个一个就行吧。
即可以调度
schedule方法。
submit方法就是运行线程呗。
看你任务的实时性啊,任务如果需要迅速得到响应那必须分开使用线程池啊
我觉得你分析的很好,到时候压力测试下,看看效果
已解决问题
未解决问题Java中的多线程你只要看这一篇就够了 - 简书
Java中的多线程你只要看这一篇就够了
如果对什么是线程、什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内。
用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现。说这个话其实只有一半对,因为反应“多角色”的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法模拟,当然也没法说能用单线程来实现:比如最常见的“生产者,消费者模型”。
很多人都对其中的一些概念不够明确,如同步、并发等等,让我们先建立一个数据字典,以免产生误会。
多线程:指的是这个程序(一个进程)运行时产生了不止一个线程
并行与并发:
并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。
并发与并行
线程安全:经常用来描绘一段代码。指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。反过来,线程不安全就意味着线程的调度顺序会影响最终结果,如不加事务的转账代码:
void transferMoney(User from, User to, float amount){
to.setMoney(to.getBalance() + amount);
from.setMoney(from.getBalance() - amount);
同步:Java中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问成为线程安全,来保证结果的准确。如上面的代码简单加入@synchronized关键字。在保证结果准确的同时,提高性能,才是优秀的程序。线程安全的优先级高于性能。
好了,让我们开始吧。我准备分成几部分来总结涉及到多线程的内容:
扎好马步:线程的状态
内功心法:每个对象都有的方法(机制)
太祖长拳:基本线程类
九阴真经:高级多线程控制类
扎好马步:线程的状态
先来两张图:
线程状态转换
各种状态一目了然,值得一提的是"Blocked"和"Waiting"这两个状态的区别:
线程在Running的过程中可能会遇到阻塞(Blocked)情况
对Running状态的线程加同步锁(Synchronized)使其进入(lock blocked pool ),同步锁被释放进入可运行状态(Runnable)。从jdk源码注释来看,blocked指的是对monitor的等待(可以参考下文的图)即该线程位于等待区。
线程在Running的过程中可能会遇到等待(Waiting)情况
线程可以主动调用object.wait或者sleep,或者join(join内部调用的是sleep,所以可看成sleep的一种)进入。从jdk源码注释来看,waiting是等待另一个线程完成某一个操作,如join等待另一个完成执行,object.wait()等待object.notify()方法执行。
Waiting状态和Blocked状态有点费解,我个人的理解是:Blocked其实也是一种wait,等待的是monitor,但是和Waiting状态不一样,举个例子,有三个线程进入了同步块,其中两个调用了object.wait(),进入了waiting状态,这时第三个调用了object.notifyAll(),这时候前两个线程就一个转移到了Runnable,一个转移到了Blocked。
从下文的monitor结构图来区别:每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。在 “Entry Set”中等待的线程状态Blocked,从jstack的dump中来看是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是Waiting,表现在jstack的dump中是 “in Object.wait()”。
此外,在runnable状态的线程是处于被调度的线程,此时的调度顺序是不一定的。Thread类中的yield方法可以让一个running状态的线程转入runnable。
内功心法:每个对象都有的方法(机制)
synchronized, wait, notify 是任何对象都具有的同步工具。让我们先来了解他们
他们是应用于同步问题的人工线程调度工具。讲其本质,首先就要明确monitor的概念,Java中的每个对象都有一个监视器,来监测并发代码的重入。在非多线程编码时该监视器不发挥作用,反之如果在synchronized 范围内,监视器发挥作用。
wait/notify必须存在于synchronized块中。并且,这三个关键字针对的是同一个监视器(某对象的监视器)。这意味着wait之后,其他线程可以进入同步块执行。
当某代码并不持有监视器的使用权时(如图中5的状态,即脱离同步块)去wait或notify,会抛出java.lang.IllegalMonitorStateException。也包括在synchronized块中去调用另一个对象的wait/notify,因为不同对象的监视器不同,同样会抛出此异常。
再讲用法:
synchronized单独使用:
代码块:如下,在多线程环境下,synchronized块中的方法获取了lock实例的monitor,如果实例相同,那么只有一个线程能执行该块内容
public class Thread1 implements Runnable {
public void run() {
synchronized(lock){
..do something
直接用于方法: 相当于上面代码中用lock来锁定的效果,实际获取的是Thread1类的monitor。更进一步,如果修饰的是static方法,则锁定该类所有实例。
public class Thread1 implements Runnable {
public synchronized void run() {
..do something
synchronized, wait, notify结合:典型场景生产者消费者问题
* 生产者生产出来的产品交给店员
public synchronized void produce()
if(this.product &= MAX_PRODUCT)
System.out.println("产品已满,请稍候再生产");
catch(InterruptedException e)
e.printStackTrace();
this.product++;
System.out.println("生产者生产第" + this.product + "个产品.");
notifyAll();
//通知等待区的消费者可以取出产品了
* 消费者从店员取产品
public synchronized void consume()
if(this.product &= MIN_PRODUCT)
System.out.println("缺货,稍候再取");
catch (InterruptedException e)
e.printStackTrace();
System.out.println("消费者取走了第" + this.product + "个产品.");
this.product--;
notifyAll();
//通知等待去的生产者可以生产产品了
多线程的内存模型:main memory(主存)、working memory(线程栈),在处理数据时,线程会把值从主存load到本地栈,完成操作后再save回去(volatile关键词的作用:每次针对该变量的操作都激发一次load and save)。
针对多线程使用的变量如果不是volatile或者final修饰的,很有可能产生不可预知的结果(另一个线程修改了这个值,但是之后在某线程看到的是修改之前的值)。其实道理上讲同一实例的同一属性本身只有一个副本。但是多线程是会缓存值的,本质上,volatile就是不去缓存,直接取值。在线程安全的情况下加volatile会牺牲性能。
太祖长拳:基本线程类
基本线程类指的是Thread类,Runnable接口,Callable接口
Thread 类实现了Runnable接口,启动一个线程的方法:
  MyThread my = new MyThread();
  my.start();
Thread类相关方法:
//当前线程可转让cpu控制权,让别的就绪状态线程运行(切换)
public static Thread.yield()
//暂停一段时间
public static Thread.sleep()
//在一个线程中调用other.join(),将等待other执行完后才继续本线程。    
public join()
//后两个函数皆可以被打断
public interrupte()
关于中断:它并不像stop方法那样会中断一个正在运行的线程。线程会不时地检测中断标识位,以判断线程是否应该被中断(中断标识值是否为true)。终端只会影响到wait状态、sleep状态和join状态。被打断的线程会抛出InterruptedException。
Thread.interrupted()检查当前线程是否发生中断,返回boolean
synchronized在获锁的过程中是不能被中断的。
中断是一个状态!interrupt()方法只是将这个状态置为true而已。所以说正常运行的程序不去检测状态,就不会终止,而wait等阻塞方法会去检查并抛出异常。如果在正常运行的程序中添加while(!Thread.interrupted()) ,则同样可以在中断后离开代码体
Thread类最佳实践:
写的时候最好要设置线程名称 Thread.name,并设置线程组 ThreadGroup,目的是方便管理。在出现问题的时候,打印线程栈 (jstack -pid) 一眼就可以看出是哪个线程出的问题,这个线程是干什么的。
如何获取线程中的异常
不能用try,catch来获取线程中的异常
与Thread类似
future模式:并发模式的一种,可以有两种形式,即无阻塞和阻塞,分别是isDone和get。其中Future对象用来存放该线程的返回值以及状态
ExecutorService e = Executors.newFixedThreadPool(3);
//submit方法有多重参数版本,及支持callable也能够支持runnable接口类型.
Future future = e.submit(new myCallable());
future.isDone() //return true,false 无阻塞
future.get() // return 返回值,阻塞直到该线程运行结束
九阴真经:高级多线程控制类
以上都属于内功心法,接下来是实际项目中常用到的工具了,Java1.5提供了一个非常高效实用的多线程包:java.util.concurrent, 提供了大量高级工具,可以帮助开发者编写高效、易维护、结构清晰的Java多线程程序。
1.ThreadLocal类
用处:保存线程的独立变量。对一个线程类(继承自Thread)
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。常用于用户登录控制,如记录session信息。
实现:每个Thread都持有一个TreadLocalMap类型的变量(该类是一个轻量级的Map,功能与map一样,区别是桶里放的是entry而不是entry的链表。功能还是一个map。)以本身为key,以目标为value。
主要方法是get()和set(T a),set之后在map里维护一个threadLocal -& a,get时将a返回。ThreadLocal是一个特殊的容器。
2.原子类(AtomicInteger、AtomicBoolean……)
如果使用atomic wrapper class如atomicInteger,或者使用自己保证原子的操作,则等同于synchronized
//返回值为boolean
AtomicInteger.compareAndSet(int expect,int update)
该方法可用于实现乐观锁,考虑文中最初提到的如下场景:a给b付款10元,a扣了10元,b要加10元。此时c给b2元,但是b的加十元代码约为:
if(b.value.compareAndSet(old, value)){
//try again
// if that fails, rollback and log
AtomicReference
对于AtomicReference 来讲,也许对象会出现,属性丢失的情况,即oldObject == current,但是oldObject.getPropertyA != current.getPropertyA。
这时候,AtomicStampedReference就派上用场了。这也是一个很常用的思路,即加上版本号
lock: 在java.util.concurrent包内。共有三个实现:
ReentrantLock
ReentrantReadWriteLock.ReadLock
ReentrantReadWriteLock.WriteLock
主要目的是和synchronized一样, 两者都是为了解决同步问题,处理资源争端而产生的技术。功能类似但有一些区别。
区别如下:
lock更灵活,可以自由定义多把锁的枷锁解锁顺序(synchronized要按照先加的后解顺序)
提供多种加锁方案,lock 阻塞式, trylock 无阻塞式, lockInterruptily 可打断式, 还有trylock的带超时时间版本。
本质上和监视器锁(即synchronized是一样的)
能力越大,责任越大,必须控制好加锁和解锁,否则会导致灾难。
和Condition类的结合。
性能更高,对比如下图:
synchronized和Lock性能对比
ReentrantLock    
可重入的意义在于持有锁的线程可以继续持有,并且要释放对等的次数后才真正释放该锁。
使用方法是:
1.先new一个实例
static ReentrantLock r=new ReentrantLock();
r.lock()或r.lockInterruptibly();
此处也是个不同,后者可被打断。当a线程lock后,b线程阻塞,此时如果是lockInterruptibly,那么在调用b.interrupt()之后,b线程退出阻塞,并放弃对资源的争抢,进入catch块。(如果使用后者,必须throw interruptable exception 或catch)
r.unlock()
必须做!何为必须做呢,要放在finally里面。以防止异常跳出了正常流程,导致灾难。这里补充一个小知识点,finally是可以信任的:经过测试,哪怕是发生了OutofMemoryError,finally块中的语句执行也能够得到保证。
ReentrantReadWriteLock
可重入读写锁(读写锁的一个实现)
  ReentrantReadWriteLock lock = new ReentrantReadWriteLock()
  ReadLock r = lock.readLock();
  WriteLock w = lock.writeLock();
两者都有lock,unlock方法。写写,写读互斥;读读不互斥。可以实现并发读的高效线程安全代码
这里就讨论比较常用的两个:
BlockingQueue
ConcurrentHashMap
BlockingQueue
阻塞队列。该类是java.util.concurrent包下的重要类,通过对Queue的学习可以得知,这个queue是单向队列,可以在队列头添加元素和在队尾删除或取出元素。类似于一个管  道,特别适用于先进先出策略的一些应用场景。普通的queue接口主要实现有PriorityQueue(优先队列),有兴趣可以研究
BlockingQueue在队列的基础上添加了多线程协作的功能:
BlockingQueue
除了传统的queue功能(表格左边的两列)之外,还提供了阻塞接口put和take,带超时功能的阻塞接口offer和poll。put会在队列满的时候阻塞,直到有空间时被唤醒;take在队 列空的时候阻塞,直到有东西拿的时候才被唤醒。用于生产者-消费者模型尤其好用,堪称神器。
常见的阻塞队列有:
ArrayListBlockingQueue
LinkedListBlockingQueue
DelayQueue
SynchronousQueue
** ConcurrentHashMap**
高效的线程安全哈希map。请对比hashTable , concurrentHashMap, HashMap
管理类的概念比较泛,用于管理线程,本身不是多线程的,但提供了一些机制来利用上述的工具做一些封装。
了解到的值得一提的管理类:ThreadPoolExecutor和 JMX框架下的系统级管理类 ThreadMXBean
ThreadPoolExecutor
如果不了解这个类,应该了解前面提到的ExecutorService,开一个自己的线程池非常方便:
ExecutorService e = Executors.newCachedThreadPool();
ExecutorService e = Executors.newSingleThreadExecutor();
ExecutorService e = Executors.newFixedThreadPool(3);
// 第一种是可变大小线程池,按照任务数来分配线程,
// 第二种是单线程池,相当于FixedThreadPool(1)
// 第三种是固定大小线程池。
// 然后运行
e.execute(new MyRunnableImpl());
该类内部是通过ThreadPoolExecutor实现的,掌握该类有助于理解线程池的管理,本质上,他们都是ThreadPoolExecutor类的各种实现版本。请参见javadoc:
ThreadPoolExecutor参数解释
翻译一下:
corePoolSize:池内线程初始值与最小值,就算是空闲状态,也会保持该数量线程。
maximumPoolSize:线程最大值,线程的增长始终不会超过该值。
keepAliveTime:当池内线程数高于corePoolSize时,经过多少时间多余的空闲线程才会被回收。回收前处于wait状态
时间单位,可以使用TimeUnit的实例,如TimeUnit.MILLISECONDS 
workQueue:待入任务(Runnable)的等待场所,该参数主要影响调度策略,如公平与否,是否产生饿死(starving)
threadFactory:线程工厂类,有默认实现,如果有自定义的需要则需要自己实现ThreadFactory接口并作为参数传入。
请注意:该类十分常用,作者80%的多线程问题靠他。
阿里巴巴技术专家
需要内推阿里,蚂蚁金服,菜鸟的可以私信联系我
机器学习爱好者
单词量早日上2w
引 如果对什么是线程、什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内。 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现。说这个话其实只有一半对,因为反应“多角色”的程序代码,最起码每个角色要给他一个线...
文章来源:http://www.54tianzhisheng.cn//Java-Thread/ 第一章 —— Java 多线程技能 线程技术点: 线程的启动 如何使线程暂停 如何使线程停止 线程的优先级 线程安全相关问题 进程和线程的概念及多线程的优点 ...
一、进程和线程 进程 进程就是一个执行中的程序实例,每个进程都有自己独立的一块内存空间,一个进程中可以有多个线程。比如在Windows系统中,一个运行的xx.exe就是一个进程。 每个进程有各自独立的一块内存,使得各个进程之间内存地址相互隔离。 线程 线程是指进程中的一个执...
本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲一下进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。 线程:同一类线程共享代码...
Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递...
9月30日,守护宝F5远程控制手机继在京东成功首发之后,又在守护宝天猫官方旗舰店、苏宁易购天猫官方旗舰店以及守护宝苏宁官方旗舰店正式开卖。至此,守护宝F5四店齐发,实现该产品在三大主流电商平台全渠道覆盖,普惠用户,为消费者提供便捷高效的购买渠道。 继今年7月在京东首发以来,...
W: 我 LG: 老公 001 LG: 这汤不太好喝。 W: 怎么不好喝了?! LG: 骨头上的肉太粗糙,茶树菇太韧,不好嚼。 W: 那不喝了呗。我就是这么煮的。爱喝不喝。 LG:……不是好好说话吗?我只是在给你提建议,下次才有进步呀! W: 不煮了!不吃了! LG: ……...
人生15项缺失 1.自我意识的建立和觉察 2.有效沟通 3.与感觉在一起 8.面对冲突及处理问题的能力
节日就是个理由一些时候也是个借口,从小在不过节日的环境之中长大,节日更多时候对我是一个负担。后天就是教师节了,今天收到咱们部门同事的礼物,一束鲜花还有有心的小卡片,非常意外当然也非常开心,毕竟鲜花这样美好的礼物还是让人难以拒绝,带来充足的精神愉悦!
在好早之前读过...
思考:对于做笔记方法,听完这节课后突然发现自己依然还处在初级阶段。 虽然每天的工作也在做规划,但并没有像文中提到的那样详细。 接下来该如何做? 首先,还是那句话:好记性不如烂笔头,每天需要做的事情还是要提前做好规划,但不同于以前的是,接下来没完成一件事情需要用不同颜色的笔进...这是一道Java线程的问题,在eclipse上运行了下发现没有任何输出,请大神解答一下。_百度知道
这是一道Java线程的问题,在eclipse上运行了下发现没有任何输出,请大神解答一下。
守护线程,两个线程的执行顺序。
public class A extends Thread {
setDaemon(true);
public void run(){
(new B()).start();
Thread.sleep(60);
System.out.println(&A done&);
catch(InterruptedException x...
我有更好的答案
因为你一开始这个程序就没有线程在执行了, A作为守护线程,发现没有任何线程执行,自动退出,根本不会执行run里面的业务代码的也就是但这个程序还有其他线程在执行, 守护线程才会去执行run里面的代码要实现输出, 就在main方法里面new一个B线程,让程序一开始就有一个非守护线程在执行public&static&void&main(String[]args){&&&&&&&&A&a=new&A();&&&&&&&&a.start();&&&&&&&&&&&&&&&&new&B().start();&&&&}
但是您给的new B().start()这段代码写在a.start()之后,是不是可能出现:1、a先启动,B后启动a退出,B中的run执行并输出;2、B先启动,a后启动,a作为B的守护线程,a和B都可能输出。我分析的对么?
这有关系吗?
B里面休眠时间那么长, 无论如何AB都会输出
这道题我懂了,我觉得您答得挺好的,但我还想补充下,main()函数也是用户线程,如果main()函数里加一条Thread.sleep(...)秒a.start()后也会有输出。意思就是只要存在用户线程没有结束,守护线程就可以输出。
采纳率:59%
来自团队:
代码里面全是异常处理,没有输出当然就没输出了
为您推荐:
其他类似问题
线程的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。求大神帮我修改一下Java程序!_百度知道
求大神帮我修改一下Java程序!
我的程序最后一行有问题,应该怎么改?
String sName,sID;
Scanner sc=new Scanner(System.in);
sName=sc.next();
sID=sc.nextLine();
System.out.printf(&我叫%s,我的学号是%s%n&,sName,sID);
System.out.printf(&我姓...
我有更好的答案
System.out.printf(&我的学院编号:%s&+sID.substring(1, 2)+&,班编号:%s&+sID.substring(3, 2)+&,顺序号:%s%n&+sID.substring(5, 4));
请问printf(格式化字符串,输出参数表)这种格式怎么写?能告诉我原来的写法中哪里出错了吗?
采纳率:54%
输出16进制,可以使用System.out.printf(&%04X&, (int)name.charAr(0));
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。}

我要回帖

更多关于 java程序员简历 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信