线程的概述
省略啦,这个我就不去复制拷贝了,大家自己去理解一下,从计算机的角度。
线程的创建方式
1、继承Thread,实现run方法
public class HelloThread extends Thread{
@Override
public void run() {
System.out.println("thread name: "+Thread.currentThread().getName());
}
}
调用方式:thread.start就可以了,如果直接调用run方法,也可以运行但是还是在本线程中。
public class Thread1Test {
public static void main(String[] args) {
Thread1 thread= new Thread1();
thread.start();
}
}
2、实现Runnable接口
public class RunnableThread implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("hello");
}
}
调用方式:先new Thread,然后还是调用start方法。
线程其他相关的方法
1、join 表示等待线程执行完 join(0)表示无限期等待
Thread thread1=new Thread(new RunnableThread());
thread1.start();
try {
thread.join();//等待线程执行完,在结束自己的线程
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
2、yield 表示现在当前线程可以空出cpu,但也只是建议,并不能保证。
3、sleep就比较简单了,但注意睡眠时间也并不是完全精确
线程的特性及存在问题
多个线程可以共享内存是线程的一大特性,这个特性也带来了相关的问题,可以说线程的并发问题都是因为这个特性引起的。
问题
1、竞态条件
多个线程访问同一个变量时就会存在问题,原因是因为当给一个变量赋值的时候是有三个步骤的:
1)取出当前变量的值
2)在取出的值上去做操作
3)将新的值赋值给变量
所以可能多个线程会同时做第一步,那这个变量就没有被操作正确。
2、内存可见性
指的是一个线程修改一个共享变量,另一个线程不一定能立马看到,甚至永远看不到。原因是因为,计算机会有各种缓存,包括cpu会有寄存器等等,一般写数据可能是先写到缓存里面,稍后才会写到内存,读数据也可能是从缓存里面读。所以就可能会造成数据读取的不正确。
总结
以上是线程基本的概念,以及因为共享内存的特性引发的问题,其实关于线程的特性以及引发的问题才是我们关注的重点,后面我们都是在解决这些出现的问题,只是通过不同的方法和手段而已。下一章我们将一起学习synchronized关键字。