多线程,实现Runnable接口

Scaarf 2017-11-08 07:47:15
不是说实现Runnable接口可以实现资源共享吗,为啥我的结果运行却有重复的数字。。。。还是我哪写错了

class A implements Runnable{
private static int totalTicketNumber=100;
private String name;
public A(String name) {
this.name=name;
}

@Override
public void run() {
for (int j = 0; j < 5; j++) {
totalTicketNumber--;
System.out.println(totalTicketNumber);
}
}

public static void main(String[] args) throws InterruptedException {
String name="线程";
A a=new A(name);
for (int i = 1; i <= 5; i++) {
Thread t=new Thread(a);
t.start();
}
}

}
...全文
760 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
totalTicketNumber是共享资源,并发访问的情况下,需要加锁
Scaarf 2017-11-15
  • 打赏
  • 举报
回复
引用 9 楼 sunle818 的回复:
其实这个问题很你自己解决也很简单: 首先你要搞清楚线程运行的特性是什么,然后所有其它的问题就解决了: 这里我给你解释一下吧, 自己new出来的线程和主线程是一起并行运行的,也就是在同时执行。 那么为什么同时执行,为什么会出现数据覆盖的效果了? 重点: cpu执行程序的时候,如果这个程序有很多线程在同时运行, 那么它会将控制这个程序的每一个时间段都分成N个时间片, 而每个线程在同一个时间段执行时,都有可能会拥有这个时间段的一小片运行时间, 举例: 如果有AB两个线程同时执行 在线程A执行了一半的时候,CPU有可能会丢下A线程,然后再去调度B线程一会。 这时候如果AB线程操作的是同一个数据,那么就可能会出现覆盖的情况。 因为,那一个线程获得多少执行时间是CPU控制的, 有可能A线程执行了一半被放下了,然后B线程执行完了再执行A线程。 也有可能A执行一会,B执行一会,这样交替执行,这只能是CPU来决定。 但是这段时间中有可能也在调度其它的程序执行。 如果你想要在这个时候获取准确数据,就要用JDK提供的synchronrized()方法来锁定你的对象。 太卡了:synchronrized()简单的说就是在执行这段代码的时候,它又回到了单线程执行的时代。 在同一个时间只允许一个线程访问。
synchronrized()会用也理解,现在不明白的就单这个程序来说,既然CPU每个时间片只能执行一个线程中的某一片段代码,那就不存在多个线程同时对总票数进行修改的问题,那为啥要加同步呢,最多就是读取到的数据不实时,但最后的结果应该是对的,反正就想不通这一点,求指点。。。。。。。
Ckuangf 2017-11-12
  • 打赏
  • 举报
回复
楼主了解一下并发和同步,sychornized和lock
guohezhibingzu 2017-11-12
  • 打赏
  • 举报
回复
6楼很给力。。。
lhqgood 2017-11-10
  • 打赏
  • 举报
回复
共享资源totalTicketNumber,没有上锁
lcyzc 2017-11-10
  • 打赏
  • 举报
回复
通过synchronized关键字来实现同步,可以用同步代码块或者同步方法
昨夜的雨 2017-11-09
  • 打赏
  • 举报
回复
多个线程共同操作的同一个数据(变量)就叫共享数据。 多个线程操作共享数据(本题为 totalTicketNumber),当其中一个线程操作共享数据时,未执行完毕的情况下,另一个线程也参与共享数据的操作,这时就会导致共享数据出现安全问题。 怎么解决? 我们让一个线程操作共享数据完毕的情况下,其他的线程才有机会参与共享数据的操作。 java语言中,使用线程的同步机制处理线程的安全问题,有两种办法:①同步代码块 synchronized(同步监视器){//同步监视器 即为锁,任何类的对象都可以充当锁,必须保 //证所有的线程公用同一把锁 //操作共享数据的代码 } ②同步方法 将操作共享数据的代码分离出来,声明为一个 synchronized的方法 如: public synchronized void show(){ //操作共享数据的代码 } 本题中,我们使用同步代码块处理线程的安全问题,处理如下 synchronized(this){//this表示当前对象, totalTicketNumber--; System.out.println(totalTicketNumber); }
捏造的信仰 2017-11-09
  • 打赏
  • 举报
回复
每个线程要独自运行各自的 Runnable 对象,也就是说你应该这样用:
Thread t = new Thread(new A())
而不是同一个 A 对象丢给每个 Thread。因为 Thread 是同时运行的,你这样就乱了。
uranusfire 2017-11-09
  • 打赏
  • 举报
回复
并发,你的方法没有加锁,当你一个线程运行时,当执行到这个方法时其他线程也可能访问改方法,导致结果一样。
  • 打赏
  • 举报
回复
其实这个问题很你自己解决也很简单: 首先你要搞清楚线程运行的特性是什么,然后所有其它的问题就解决了: 这里我给你解释一下吧, 自己new出来的线程和主线程是一起并行运行的,也就是在同时执行。 那么为什么同时执行,为什么会出现数据覆盖的效果了? 重点: cpu执行程序的时候,如果这个程序有很多线程在同时运行, 那么它会将控制这个程序的每一个时间段都分成N个时间片, 而每个线程在同一个时间段执行时,都有可能会拥有这个时间段的一小片运行时间, 举例: 如果有AB两个线程同时执行 在线程A执行了一半的时候,CPU有可能会丢下A线程,然后再去调度B线程一会。 这时候如果AB线程操作的是同一个数据,那么就可能会出现覆盖的情况。 因为,那一个线程获得多少执行时间是CPU控制的, 有可能A线程执行了一半被放下了,然后B线程执行完了再执行A线程。 也有可能A执行一会,B执行一会,这样交替执行,这只能是CPU来决定。 但是这段时间中有可能也在调度其它的程序执行。 如果你想要在这个时候获取准确数据,就要用JDK提供的synchronrized()方法来锁定你的对象。 太卡了:synchronrized()简单的说就是在执行这段代码的时候,它又回到了单线程执行的时代。 在同一个时间只允许一个线程访问。
不清不慎 2017-11-09
  • 打赏
  • 举报
回复
并发,你的方法没有加锁,当你一个线程运行时,当执行到这个方法时其他线程也可能访问改方法,导致结果一样。
ZL_LSY 2017-11-09
  • 打赏
  • 举报
回复
public synchronized void run() { for (int j = 0; j < 5; j++) { totalTicketNumber--; System.out.println(totalTicketNumber); } } 锁上就好了
mmqw 2017-11-09
  • 打赏
  • 举报
回复
需要加个锁
u010222066 2017-11-09
  • 打赏
  • 举报
回复
因为 totalTicketNumber-- 操作不是原子操作,需要加锁
  • 打赏
  • 举报
回复
每一次使用Thread的时候都需要一个A,也就是一个实现了runnable的对象,你在循环的时候就一直在使用一个A,所以就一样。

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧