前面我们学了ArrayList和LinkedList
,回顾学习地址:
http://blog.csdn.net/github_26672553/article/details/75006230
Thread类
该类继承接口Runnable
,启动一个线程代码案列。
Thread t = new Thread();
t.start();//这个方法是代表启动一个线程
只不过上面代码就这样写 没有什么意义。
new Thread()
的时候需要传入参数(一个继承Runnable
类的对象,或者匿名内部类)。
如果业务稍微复制推荐自定义一个继承Runnable
的类。
比如MyThread.java
:
public class MyThread implements Runnable {
@Override
public void run() {
System.out.println("hello");
}
}
我们在入口函数中演示开启5个线程:
public static void main(String[] args) throws InterruptedException{
for (int i=1;i<=5;i++){
Thread thread = new Thread(new MyThread());
thread.start();
}
}
运行程序会输出 5个abc
。
这就是Java的多线程
。
ArrayList的线程不安全
1、改造一下MyThread.java文件代码:
import java.util.List;
public class MyThread implements Runnable {
private List<String>list;
public MyThread(List<String> list) {
this.list = list;
}
@Override
public void run() {
for (int i=1;i<=50;i++){
this.list.add("hi");
}
}
}
添加一个List类型的属性,在类构造函数中要求参数传入并保存。run()
方法添加50个hi字符串。
2、程序入口文件
public static void main(String[] args) throws InterruptedException{
List<String> list = new ArrayList<String>();
for (int i=1;i<=5;i++){
Thread thread = new Thread(new MyThread(list));
thread.setName("t-"+String.valueOf(i)); //给线程起个名字
thread.start();
}
//主线程
System.out.println(list.size()); //多次运行程序 发现打印的值不一样
}
给5个子线程 都传入list
对象了,最后在主线程输出list
的大小,但多次运行程序发现值有变化,有时是250
有时是200
。
这个情况就是ArrayList的线程不安全
。
List<String> list = new Vector<String>();
换成Vector
后每次运行结果都是一样,说明Vector
是线程安全的。
但也不是绝对的,如果子线程执行时间太长,主线程就执行了呢?
意思是:如果子线程还在往list
里添加数据,比如循环10000次,这个时候可能后面主线程就已经开始执行了。
要解决主线程必须在子线程执行完毕之后 才执行
简单的解决方法:Thread.join
。
线程B中调用了线程A的Join()
方法,知道线程A执行完毕后,才会继续执行线程B。
public static void main(String[] args) throws InterruptedException{
// 用来装 线程 的对象
List<Thread> threadList = new ArrayList<Thread>();
// list对象
List<String> list = new Vector<String>();
for (int i=1;i<=5;i++){
Thread thread = new Thread(new MyThread(list));
thread.setName("t-"+String.valueOf(i)); //给线程起个名字
thread.start();
threadList.add(thread); //把子线程装进去
}
for (Thread thread:threadList){
thread.join();
}
//主线程
System.out.println(list.size()); //多次运行程序 发现打印的值不一样
}