说起线程要说下线程的概念:线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程(摘自百度);对此不多赘述。一个线程就是一条执行路径,java是支持多线程的语言之一,因而运行在一个应用程序中同时执行多条执行路径,也就是同时运行多条线程,这里说的“同时”是说的宏观上的概念,单核cup是不存在绝对意义上的同时,同时运行的多个线程是指,这多个线程拥有的线程同时拥有cup的执行权和执行资格。
所谓“执行权”是指cup瞬时正在执行的线程就拥有执行权;“执行资格”;是指此时的线程当前cup没有执行它但他有资格:
由此引出线程的状态,状态图如下:
·
下面代码结合这个图做解释,重点关注红色圆圈内的状态
public class ThreadDemo extends Thread{
/*
* 这是创建线程的有两种方式,这是创建线程的第一种方式:直接继承Thread类
*/
/**
* run方法内是线程执行的任务,调用线程的start()方法后就会调用run方法
*/
@Override
public void run() {
super.run();
while(true ){
//Thread.currentThread()取得当前正在运行的线程的name从0开始编号
System.out.println(Thread.currentThread().getName()+"正在运行");
}
}
}
public class Test {
public static void main(String[] args) {
// 此时处于线程的new状态
Thread thread1 = new ThreadDemo();
Thread thread2 = new Thread(new ThradDemo2());
/*
* 处于线程的Runable状态也就是具有执行资格, cup自动做着快速的切换当cup切换到这个线程
* 的时候cup就获得了执行权就会处于Running状态
*/
thread1.start();
thread2.start();
}
}
创建好的线程,也就是实例化的线程是没有被执行的,当线程调用了start方法之后线程才有了生命才开始执行。注意的是直接调用线程的run()方法是没有用的,那跟调用一个对象中的普通方法没有区别要使用线程的start()方法开启线程;
好了有了这些简单的储备之后就写几个demo来比较深入的理解java的多线程,不可避免的问题是多个线程操作同一个资源时会产生线程问题,举个简单的例子来讲,有两个相同的线程任务,这两个线程任务都是同时往一个整形变量里进行加一的操作并输出,就会出现输入相同数字的问题,问题产生的原因就是没有做到线程同步,就是说一个线程任务对变量进行了加一的操作后还没有输出就被两个线程任务夺走了线程的执行权,两一个线程任务拿走执行权后对变量进行加一操作后输出,第一个线程任务获得执行权开始执行刚刚没有完成的任务也就是输出数值,这时候的数值已经变了。
解决的方法无非就是保证线程任务的原子性,就是说说一致性就执行到底,请看下面的demo
public class Resource implements Runnable {
int num = 1;
public synchronized void set() {
System.out.println(Thread.currentThread().getId() + "**********" + (num++));
}
@Override
public void run() {
while (true) {
set();
}
}
}
public class Test {
public static void main(String[] args) {
Resource r = new Resource();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
以上代码解决了线程同步问题,下一章讨论下Synchronized这个关键字