线程是进程的组成部分,一个进程可以拥有多个线程。线程在程序中是独立的、并发的执行流,他们共享进程中的内存和进程应有的状态。
java多线程有三种实现方式,一种是继承Thread类,重写run方法;第二种是实现Runnable接口,重写run方法;第三种是实现Callable接口,重写call方法。
启动一个线程可以通过调用Thread的子类的start()方法来启动。
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " "
+ i);
}
}
});
/**
* 设置线程名字
* */
thread.setName("我的线程");
/**
* 启动线程,但该线程并不会立即执行,只是让该线程处于就绪状态,
* 什么时候执行是由系统来决定的,不受程序的控制
* */
thread.start();
/**
* 阻塞(休眠)线程1秒钟(毫秒为单位),系统在该线程休眠时将cpu让给其它线程,
* 而当前线程休眠完毕将进入就绪状态
* */
thread.sleep(1000);
/**
* 判断线程是否死亡,当线程处于就绪、运行、阻塞三阶段为true,
* 新建、死亡为false
* */
thread.isAlive();
/**
* 设置该线程为后台线程(守护线程),比如JVM的垃圾回收线程就是典型的后台线程。
* 当前台线程全部死亡的时候,虚拟机退出,后台线程也就跟着死亡,即使后台线程run方法没有执行完毕。
* */
thread.setDaemon(true);
/**
* yield(线程让步)与sleep一样,让线程暂停,但它不会阻塞线程,它只是让线程转入就绪状态。
* yield只是让当前线程暂停一下,让系统的线程调度器重新调度一次。
* 完全可能的情况是:当某个线程调用了yield方法暂停之后,线程调度器又将其调度出来重新执行。
* */
thread.yield();
/**
* 设置线程的优先级别,也就是线程调度的优先级别。数字越大就越优先被系统分配cup调用执行。
* setPriority方法的参数可以是一个整数,范围是1~10之间。
* */
thread.setPriority(Thread.MAX_PRIORITY);
thread.setPriority(Thread.MIN_PRIORITY);
/**
* 直接停止该线程,释放该线程的所有锁,导致数据不一致,不安全,不推荐使用。
* */
thread.stop();
多线程需要考虑线程安全问题,如果有多个线程调用同一方法,而该方法对数据进行了修改,那么就需要考虑同步。
线程同步有三种实现方式:
1.同步代码块
synchronized(obj){
}
2.同步方法
public synchronized void test(){
}
3.lock锁
public static ReentrantLock lock = new ReentrantLock();
public static void test(){
lock.lock();
try {
if(i==50){
Thread.sleep(10);
i--;
}
} catch (Exception e) {
e.printStackTrace();
} finally{
lock.unlock();
}
}