Java中多线程概述
一、基本概念
进程和线程
- 进程是程序运行的实例,比如Java程序就是一个Java虚拟机进程
- 每个进程中可以包含多个线程,每个线程完成各自不同的任务,在Java平台中一个线程对应一个对象
但是这个对象和普通类中声明的对象不一样,不是分配在对空间中的;而是,JVM会给每个线程分配一个栈空间,这个和普通对象还是有区别的
Java中线程的使用
- 继承
Thread
类,重写run()
方法(线程实现人任务的入口);主方法中实例化子类后使用start()
启用 - 实现
Runnable
接口,主方法中实例化实现类,该实例 作为Thread
类构造参数实例化,调用start()
方法启用可以使用同一个
Runnable
实例作为参数构造多个线程,实现数据共享
Java中线程具体体现
- Java进程运行,Java虚拟机启动的时候会创建一个main线程,执行Java程序入口方法,即main方法
并不是main方法是线程,它只是主函数线程栈中的一个栈帧,也就是说Java程序运行中有一个线程是负责执行主方法的。
start()
方法启动线程,调度是由Java虚拟机调度的,线程的run()
方法执行结束时,这个线程也就结束了;start()
方法只能调用一次,不能重复调用,会报错- Java中任何一段代码都是被某一个线程所执行(所有线程都是执行main函数的主线程创建的,可以嵌套),通过
static Thread currentThread()
静态方法查看当前代码段被哪个线程所执行同时,一段代码可以被多个线程执行,比如实现
Runnable
方法创建线程时,使用同一个Runnable
实例就是这种效果
Java中Thread类
- 常用属性:tid,name,daemon,priority
- 常用方法:
public static native Thread currentThread(); public void run() void start() void join()//A调用B.join(),即当B执行完,才会执行A线程任务 static void yield() static void sleep(long millis)
线程的状态和调度
- 6种状态
- Java种多个线程抢占式调度,就会造成竞态(结果的正确与否和时间有关)和上下文切换。
二、多线程使用中的安全性
- 因为共享变量的存在导致运行结果可能出现不同的情况
- 产生竞争状态的几种情况:
-
多个线程对临界区进行读+改+写,会导致脏读或者丢失修改(一个线程读了另一个线程写之前的,或者两者同时写一个变量等)
-
多个线程判断+执行,其中判断条件的更改无法同步导致的错误执行
public class RaceState { public static void main(String[] args) throws InterruptedException { ThreadTask threadTask = new ThreadTask(); Thread thread1 = new Thread(threadTask); Thread thread2 = new Thread(threadTask); Thread thread3 = new Thread(threadTask); Thread thread4 = new Thread(threadTask); thread1.start(); //Thread.currentThread().sleep(1000); thread2.start(); thread3.start(); thread4.start(); } static class ThreadTask implements Runnable{ private int count = 0; @Override public void run() { do{ count++; showCount(); }while (count < 100); } private void showCount(){ System.out.println(Thread.currentThread().getName() + ":" + count); } } }
可以看出 两个线程出现了冲突
-