精华内容
下载资源
问答
  • 2019-05-30 17:17:27

    1、非同步的自增计数,在多线程时,会导致计数错误。丢失i100,存在重复i值

    package xyz.jangle.thread.test;
    
    /**
     * 非同步的自增计数,在多线程时,会导致计数错误。丢失i100,存在重复i值
     * 
     * @author jangle E-mail: jangle@jangle.xyz
     * @version 2019年5月30日 类说明
     */
    public class ThreadTest extends Thread {
    
    	public static Integer i = 0; // 用于自增计数
    
    	private int a;
    
    	public ThreadTest(int a) {
    		super();
    		this.a = a;
    	}
    
    	@Override
    	public void run() {
    		System.out.println("a=" + a + "这是一个单独线程的输出i" + i++);
    		super.run();
    	}
    
    	public static void main(String[] args) {
    		for (int a = 0; a <= 100; a++) {
    			new ThreadTest(a).start();
    		}
    	}
    
    }
    

     

    2、同步的自增计数,在多线程时,不会丢失i100,不存在重复i值

    package xyz.jangle.thread.test;
    
    /**
     * 同步的自增计数,在多线程时,不会丢失i100,不存在重复i值
     * @author jangle E-mail: jangle@jangle.xyz
     * @version 2019年5月30日 类说明
     */
    public class ThreadTestSync extends Thread {
    
    	public static Integer i = 0;		// 用于自增计数
    
    	private int a;
    
    	public ThreadTestSync(int a) {
    		super();
    		this.a = a;
    	}
    
    	@Override
    	public void run() {
    		synchronized (i) {
    			System.out.println("a=" + a + "这是一个单独线程的输出i" + i++);
    		}
    		super.run();
    	}
    
    	public static void main(String[] args) {
    		for (int a = 0; a <= 100; a++) {
    			new ThreadTestSync(a).start();
    		}
    	}
    
    }
    

     

    更多相关内容
  • 主要介绍了多线程计数的方法,有需要的朋友可以参考一下
  • 计数处要加lock,将其他线程计数暂时阻塞,保证计数的正确性。 如果要想实时计数实时输出,可以将计数和输出处一并lock处理,不然不同线程的计数和输出结果未必按顺序处理, 如此加锁能保证按顺序处理按顺序输出,...
  • ThreadResume示例源码下载,一个VC++线程挂起、线程唤醒,线程计数的操作实例,源码在VC6.0下可顺利编译成功,点击“开始”按钮,线程启动,在此情况下,可操作线程挂起、线程唤醒,唤醒后线程将继续执行,有兴趣请...
  • 大家在工作中肯定遇到过计数统计需求,单线程的情况下count直接定义int型就行,可是在多线程并发下会产生多个线程同时count++的情况,那么这种情况就需要用到AtomicInteger来保证int型变量操作的原子性。 ...

    大家在工作中肯定遇到过计数统计需求,单线程的情况下count直接定义int型就行,可是在多线程并发下会产生多个线程同时count++的情况,那么这种情况就需要用到AtomicInteger来保证int型变量操作的原子性。

    AtomicInteger要点阐述

    1. AtomicInteger的实现是基于CAS(Compare And Swop)原理;
    2. AtomicInteger的语义是:对AtomicInteger中维护的int型变量的操作是原子性的;
    3. AtomicInteger实现的思想是:每个线程中都会拥有共享变量的一份私有拷贝,但由于多个线程都抢着操作共享变量,当前线程的私有拷贝已经不是共享变量的最新值;当前线程的私有拷贝只有和共享变量的最新值相等时,才能获得对共享变量的操作权利,这个操作是原子性的;当前线程的私有拷贝如何追上共享变量的最新值呢?就是在循环中不停的和共享变量最新值比,如果不相等,就把自己更新成最新值,再比,不等再更新,直到自己和最新值相等才获得了对共享变量的操作权;这套规则是AtomicInteger设计的,操作其维护的int值的线程遵守之;

    需求:每一千条topic统计下各任务名称的数量,并打印

    代码:

    Map<String,AtomicInteger> comMap = new HashMap<>();
            Long scmNameSize = server.getDynamicConfig().loadNameSize();
            AtomicInteger atomicInteger = new AtomicInteger(1);
            for (HashMap<String,Object> message:msgs){
    //            LogUtil.apiDebug(topic+":" + message);
                //name字段大于设定值丢弃处理
                String name = message.get("name").toString();
                if ("big".equals(type)&&name.length() > scmNameSize){
                    String appName = message.get("dimension0").toString();
                    if(comMap.containsKey(appName)){
                        comMap.get(appName).incrementAndGet();
                    }else{
                        comMap.put(appName,atomicInteger);
                    }
                    num ++ ;
                    if(num >1000){
                        Set<Map.Entry<String, AtomicInteger>> entryseSet=comMap.entrySet();
                        for(Map.Entry<String, AtomicInteger> entry:entryseSet){
                            String appname = entry.getKey();
                            int count = entry.getValue().intValue();
                            LogUtil.apiInfo("appName:" + appname+",num:" + count+",scmNameSize:"+scmNameSize);
                        }
                        LogUtil.apiInfo("name:"+name) ;
                        comMap.clear();
                        num = 0;
                    }
                    continue;
                }
                String msg = JSONObject.fromObject(message).toString();
                list.add(new KeyedMessage<>(topic, key, msg));
            }

     

    incrementAndGet()方法就是以原子方式将当前值加 1
    展开全文
  • AlRegib,“用于纹理跟踪和线程计数的高速实时视觉系统”,IEEE信号处理手册,第1卷。 25号6,第758-762页,2018年。 @article {hu2018high,title = {用于纹理跟踪和线程计数的高速实时视觉系统},作者= {Hu,...
  • 线程计数实现多线程执行后再执行主线程,在项目中实际应用。
  • 要求主线程执行在子线程执行之后。 这个很好办,子线程都设为不是守护线程 然后处理4个子线程 我们可以让每个线程向如下 static class MyThread { public static void start(int begin, int step){ Thread t =...

      要求主线程执行在子线程执行之后。
    这个很好办,子线程都设为不是守护线程

    然后处理4个子线程

    我们可以让每个线程向如下

    static class MyThread {
            public static void start(int begin, int step){
                Thread t = new Thread(()->{
                    int localSum = 0;
                    for (int i = begin;i<=100;i+=step){
                        localSum+=i;
                    }
                });
                t.setDaemon(false);
                t.start();
            }
        }
    }

    在建立一个阻塞队列,存每个任务块的结果

     private static final LinkedBlockingQueue<Integer> queue = 
     new LinkedBlockingQueue<>(10);

    将子线程执行结果放入阻塞队列

    queue.offer(localSum);

    使用并发包的原子类对结果进行累加

     private static final AtomicInteger sum = new AtomicInteger(0);
     public static void test3()throws InterruptedException{
            int sum = 0;
            Lock lock = new ReentrantLock();
            AtomicInteger count = new AtomicInteger(0);
            for(int i = 0 ; ;i++){
                MyThread.start(i,4);
                count.getAndIncrement();
                if(i==4){
                    break;
                }
            }
            while(count.decrementAndGet()>0){
                Integer integer = null;
                while(queue.size()<=0){
                    Thread.sleep(0);
                }
                lock.lock();
                integer = queue.take();
                lock.unlock();
                sum+=Integer.valueOf(integer);
            }
            System.out.println(sum);
        }

    这样就能可以解决问题
    完整代码

    展开全文
  • Android中AsyncTask实现多线程计数,UI主线程运行,启动另一个线程计数并在UI主线程上显示.
  • java多线程 累加计数

    2022-02-18 00:07:18
    注意:本文参考java多线程累加计数_安迪爸爸-CSDN博客_多线程计数 题目与思路 给定count=0;让5个线程并发累加到1000; 思路 创建一个类MyRunnable,实现Runnable(继承Thread类也可) 定义一个公共变量count...

    目录

    题目与思路

    方法一

    方法二

    方法三

    总结


    注意:本文参考  java多线程累加计数_安迪爸爸-CSDN博客_多线程计数

    题目与思路

    给定count=0;让5个线程并发累加到1000;

    思路

    创建一个类MyRunnable,实现Runnable(继承Thread类也可)

    定义一个公共变量count(初始值为0),5个线程都可以访问到;

    创建5个线程并发递增count到1000;

    这块注意Thread和Runnable类的区别,Thread类是线程类,可以直接new Thread().start运行。而Runnable类是任务类,需要一个线程来承载任务,通过new Thread(new Runnable()).start()来运行任务。

    方法一

    将count公共变量放到测试类Test的类成员变量里,将MyRunnable类作为Test类的内部类,在Test类的main方法里创建5个线程,实现累加。

    public class Test {
    	//公共变量
    	int count=0;
    	public static void main(String[] args){
    		//new一个实现Runnable的类
    		Test test=new Test();
    		//创建5个任务
    		MyRunnable myRunnable1=test.new MyRunnable();
    		MyRunnable myRunnable2=test.new MyRunnable();
    		MyRunnable myRunnable3=test.new MyRunnable();
    		MyRunnable myRunnable4=test.new MyRunnable();
    		MyRunnable myRunnable5=test.new MyRunnable();
    		//创建5个线程
    		new Thread(myRunnable1).start();
    		new Thread(myRunnable2).start();
    		new Thread(myRunnable3).start();
    		new Thread(myRunnable4).start();
    		new Thread(myRunnable5).start();
    	}
    	//创建一个实现Runnable的类
    	class MyRunnable implements Runnable{
    		public void run() {
    			while(true){
    				//锁住的是整个MyRunnable类
    				synchronized(MyRunnable.class){
    					if(count>=1000){
    						break;
    					}
    					System.out.println(Thread.currentThread().getName()+":count:"+(++count));
    					//测试时,线程更容易切换
    					Thread.yield();
    				}
    				
    			}
    		}
    		
    	}
     
    }

    方法二

    以上代码没有问题,成功实现5个线程累加count到1000,接下来我们将上边代码稍作修改。

    将5个线程执行5个任务,修改为5个线程执行同一任务。

    将synchronized(MyRunnable.class)修改为synchronized(this)

    public class Test {
    	//公共变量
    	int count=0;
    	public static void main(String[] args){
    		//new一个实现Runnable的类
    		Test test=new Test();
    		//创建1个任务
    		MyRunnable myRunnable1=test.new MyRunnable();
    //		MyRunnable myRunnable2=test.new MyRunnable();
    //		MyRunnable myRunnable3=test.new MyRunnable();
    //		MyRunnable myRunnable4=test.new MyRunnable();
    //		MyRunnable myRunnable5=test.new MyRunnable();
    		//创建5个线程
    		for(int i=0;i<4;i++){
    			new Thread(myRunnable1).start();
    		}
    //		new Thread(myRunnable2).start();
    //		new Thread(myRunnable3).start();
    //		new Thread(myRunnable4).start();
    //		new Thread(myRunnable5).start();
    	}
    	//创建一个实现Runnable的类
    	class MyRunnable implements Runnable{
    		public void run() {
    			while(true){
    				//锁住的是同一对象
    				synchronized(this){
    					if(count>=1000){
    						break;
    					}
    					System.out.println(Thread.currentThread().getName()+":count:"+(++count));
    					//测试时,线程更容易切换
    					Thread.yield();
    				}
    				
    			}
    		}
    		
    	}
     
    }

    以上代码没有问题,成功实现5个线程累加count到1000。 

    虽然结果是一样的,但是代码实现是不一样的,代码一是创建了5个MyRunnable对象,代码二只创建了1个MyRunnable对象。考虑并发时用到的锁就是不一样的,

    代码一和代码二虽然synchronized中的锁不同,但目的都是为了括号中的锁是恒定不变的。

    synchronized(this)代表锁是this对象,代码二中之所以可以使用this,是因为几个线程使用的this都是同一个对象。

    synchronized(MyRunnable.class)代表锁是MyRunnable.class.this,因为MyRunnable.class.this是类加载到静态方法区中,是一直存在不变的,代码一中可以使用,当然代码二也可以这样写。
    代码一和代码二可以使用更通用的方式就是专门new一个锁对象,这个锁对象可以放在类成员变量里,加上static就可以一直常存。如定义成public static Object lock=new Object();代码一和代码二都可以使用synchronized(lock)来加锁。synchronized(this)这种方式主要是因为书写方便。

    方法三

    使用AtomicInteger类,来实现多线程累加,AtomicInteger类是线程安全的,使用它的优点就是我们不需要在代码里写Synchronized关键字了,这些事都交给它去做了。

    public class Test {
        static CountDownLatch cdl=new CountDownLatch(1000);;
        static AtomicInteger ai=new AtomicInteger(0);
        public static void main(String[] args) throws InterruptedException{ 
        	ExecutorService exec=Executors.newFixedThreadPool(100);
        	  for (int i = 0; i < 1000; i++) {
        		  exec.execute(new Runnable() {
    				@Override
    				public void run() {
    					System.out.println(Thread.currentThread().getName()+":"+ai.getAndIncrement());
    					cdl.countDown();
    				}
    			});
              }
        	cdl.await();
        	System.out.println(ai.get());
        	exec.shutdown();
        } 
    }

    代码中用到了CountDownLatch类,用法就是给其设定一个初始值1000,然后在不同线程中执行countDown方法,每执行一次,初始值-1,await方法就是等初始值减到0时,停止等待,否则一直等待。

    我在代码里新建了100个线程来并发累加,让我们看下最后结果。

    控制台输出如下:

     

    可以看到虽然输出不是按照顺序输出的,但是最后的结果是我们想要的结果,没有出现重复值的情况。

    总结

    这到题目只是举了一个多线程的例子,以及锁的简单知识。在实际应用中,从0累加到1000用多线程是没有意义的。因为根本不会比单线程快。就像让一个人数数,从0数到1000,或者让5个人接替数到1000,应该一个人更快点吧,5个人还要考虑配合的问题。但假如这5个人都是磕巴(口语不好),一个人每读一个数都要停顿1秒,但是让5个人协作,省去中间的等待时间,才是多线程应用的真正意义。

    多线程的真正应用应该是,任务中有等待的时间,这个等待时间如果交给一个线程做就堵塞在这块了。如果交由多个线程去做,会充分利用等待时间,去做其他事情。这才是多线程的意思。在我们日常工作中,像IO,网络,图片处理等,有些地方都是需要等待的,这几块用多线程,可能会提高效率。

    当然,也有一种情况,比如多个用户访问后台接口,每个用户访问其实都是一个单独的线程,假如想计算累计有多少次访问的话,就需要用到多线程累加。

    展开全文
  • 线程累加计数

    2019-11-07 14:28:52
    线程累加计数使用Runnable接口使用AtomicInteger加线程池 使用Runnable接口 public class ThreadTest { // 公共变量 int count = 0; public static void main(String[] args) { ThreadTest threadTest = new...
  • 假设你是架构师,请用多线程相关基础知识实现单机 环境下,在3s内实现1亿的计数,并统计亿级计数的耗时。 要求:请运用11种方法实现亿级的并发计数
  • 在上篇,我们利用线程池,信号量,倒计时相关类实现计数的功能,但运行结果总不能达到目标,我们将做以下改进。 1.首先附上源码,红色标注,是我们此次修改的地方 import javax.annotation.concurrent.ThreadSafe...
  • java多线程累加计数

    万次阅读 多人点赞 2018-03-21 15:49:29
    java多线程计数 题目 给定count=0;让5个线程并发累加到1000; 思路 创建一个类MyRunnable,实现Runnable(继承Thread类也可) 定义一个公共变量count(初始值为0),5个线程都可以访问到; 创建5个线程并发递增...
  • java并发模拟——多线程计数

    千次阅读 2018-12-13 11:08:33
    java并发模拟——多线程计数 最近在学习多线程与高并发的知识,这是一个能力进阶的必要途径。在大量的系统中,都会多多少少存在并发问题,如何更好的解决高并发是一个探究的问题。 下面我准备了一个简单的多线程...
  • 最近做多线程解压资源的时候,遇到一个偶现的计数错误。 按下面代码测试之后确定了问题。(10条线程,每条都计数1万次,最终结果按理来说是10万次。) 但是实际并不是每次运行结果都是10万。 这样的情况,需要加锁...
  • java多线程笔记–lock多线程计数 文章目录java多线程笔记--lock多线程计数1.lock多线程计数 lock:主要有可重入锁,读写锁,文件锁 1.lock多线程计数 package com.ctg.test.lock; import java.util.concurrent....
  • //从零开始 public static AtomicInteger race = new AtomicInteger(0); public static void increase() { //自增 race.incrementAndGet(); }
  • 创建一个倒数计数线程

    千次阅读 2021-05-28 14:32:25
    创建一个倒数计数线程。要求:1.该线程使用实现Runnable接口的写法;2.程序该线程每隔0.5秒打印输出一次倒数数值(数值为上一次数值减1)。 import java.util.Scanner; public class Main { public static void ...
  • 简介:CountDownLatch 是一个非常实用的多线程控制工具类,通常用来...await:使当前线程阻塞,等待计数器为 0countDown:计数器减一,计数为零时,释放所有在等待的线程实例:public class CountDownLatchDemo i...
  • java多线程递增计数

    千次阅读 2016-08-31 16:42:57
    java多线程递增计数
  • VC++ AccessConflict线程顺序启动计数,输出线程计数,以前发过Delphi版的,这个VC++版的希望给大家一些帮助,特别是VC新手哦。 运行环境:Windows/Visual C/C++
  • 编程要求:原线程创建两个新线程,实现两个新线程轮流计数的功能。 使用互斥锁完成两个子线程交替计数 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<pthread.h> ...
  • 开发语言:C#3.0 IDE:Visual Studio 2008 一... 如果任务管理器没有“线程数”列,可以【查看】>【选择列】来显示“线程计数”列。从上图可以看出,几乎所有的进程都拥有两个以上的线程。从而可以看出,线程是提供应

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 185,416
精华内容 74,166
关键字:

线程计数