一个网站的访问量反映了一个网站的活跃程度。使用一个全局变量count记录当前在线的网民人数 ,设计一个线程模拟上网行为:先对count变量加1,模拟一个新的网民正在在线,然后随机休眠一 段时间,再将count变量减1, 模拟一个网民下线行为。在主线程中,创建1000个这样的线程对 count变量进行操作,并实时显示count的值表示当前在线人数。
用Java多线程来实现上网人数的统计。以下是一个简单的示例代码,可以帮助开始:
import java.util.concurrent.atomic.AtomicInteger;
public class OnlineUsers {
private static final int THREAD_COUNT = 1000;
private static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
Thread thread = new Thread(() -> {
// 模拟上线
int onlineCount = count.incrementAndGet();
System.out.println("当前在线人数:" + onlineCount);
// 模拟上网时间
try {
Thread.sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
// 模拟下线
int offlineCount = count.decrementAndGet();
System.out.println("当前在线人数:" + offlineCount);
});
thread.start();
}
}
}
AtomicInteger
类来确保对count
变量的原子性操作,避免多线程并发访问时出现数据不一致的问题。incrementAndGet()
方法将count
自增1,并返回自增后的值,decrementAndGet()
方法将count
自减1,并返回自减后的值。incrementAndGet()
方法将count
增加1,并输出当前在线人数;当网民下线时,通过decrementAndGet()
方法将count
减少1,并输出当前在线人数。count(*)
包括了所有的列,相当于行数,在统计结果的时候,不会忽略为 NULL
的值。
count(1)
包括了忽略所有列,用 1 代表代码行,在统计结果的时候,不会忽略为 NULL 的值。
count(列名)
只包括列名那一列,在统计结果的时候,会忽略列值为空的计数,即某个字段值为 NULL 时,不统计。这里的空不是指空字符串或者 0,而是表示 null
。
执行效率上:
列名为主键,count(列名)
会比 count(1)
快;
列名不为主键,count(1)
会比 count(列名)
快;
如果表多个列并且没有主键,则 count(1)
的执行效率优于 count(*)
;
如果有主键,则 select count(主键)
的执行效率是最优的;
如果表只有一个字段,则 select count(*)
最优。