自上周主管带我看过kafka内部实现,使用Feature来做的数据批量发送之后,自此决定要学好并发编程。
因为本人在多线程上只能说是一个新手,打算从最底层的Thread一步一步记录我的学习之路。
通过Thread实现多线程的方式有两种,代码如下:
一、多线程实现(继承Thread类)
/**
* @Description:简单多线程的实现(线程不安全)
* @Author:zhangzhixiang
* @CreateDate:2018/12/21 20:30:54
* @Version:1.0
*/
public class TestThread extends Thread {
@Override
public void run() {
for (int i = 0; i<10000;i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
TestThread thread = new TestThread();
thread.start();
}
}
运行结果:
0
1
2
.
.
9999
二、多线程实现(实现Runnable接口)
1、Runnable实现类
/**
* @Description:简单多线程的实现(线程不安全)
* @Author:zhangzhixiang
* @CreateDate:2018/12/21 20:30:54
* @Version:1.0
*/
public class RunnalbeImpl implements Runnable {
@Override
public void run() {
for(int i = 0; i<10000; i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
RunnableImpl runnable = new RunnableImpl();
new Thread(runnable).start();
}
}
运行结果:同上
上面是第一种runnable写法,另一种可以通过JDK8的lambda表达式来写,代码如下:
/**
* @Description:简单多线程的实现(线程不安全)
* @Author:zhangzhixiang
* @CreateDate:2018/12/21 20:30:54
* @Version:1.0
*/
public class TestThread {
public static void main(String[] args) {
Count count = new Count();
Runnable runnable = () -> {
for (int i = 0; i < 10000; i++) {
count.increment();
}
};
List<Thread> threads = new ArrayList<>(10);
for (int i=0; i < 10; i++) {
Thread thread = new Thread(runnable);
threads.add(thread);
thread.start();
}
while(true) {
if(isAllThreadDead(threads)) {//所有线程运行结束
System.out.println(count.get());
break;
}
}
}
private static boolean isAllThreadDead(List<Thread> threads) {
for (Thread thread : threads) {
if(thread.isAlive()) {
return false;
}
}
return true;
}
}
2、Count计数类
/**
* @Description:Count计数类
* @Author:zhangzhixiang
* @CreateDate:2018/12/21 20:38:54
* @Version:1.0
*/
public class Count {
private int num;
public void increment() {
num++;
}
public int get() {
return num;
}
}
运行结果:
91561
上面的示例都是线程不安全的,从第三个示例可以看出线程不安全这一点,示例中同时运行了10个线程,并且每个线程循环10000次每次自增1,按正常的逻辑,返回的结果应该是10万,但实际运行结果是91561,为什么呢??原因是因为多线程具有三种特性,分别是原子性、可见性、有序性。而这里count对象对于10个线程来说是共享资源,由于这10个线程发生了并发,每次取到的数值有可能不是其他线程计算完后得到的count,这就会造成最后结果不是10万而是一个不准确的值。
如何实现线程安全的多线程呢?请见下一篇文章: