多线程
## 概述
多线程是为了解决,提高程序的执行效率或者从根本上提高CPU的执行效率
## 进程和线程
进程 就是正在运行的程序,一个软件的运行可以有一个或者多个进程
线程 操作系统能够进行运算调度的最小单位,是进程的实际运作单位
一个软件的运行至少依赖一个进程 ,一个进程的运行至少依赖一个线程
进程有独立的存储空间,可以存线程,也可以有多个线程共享的空间、
线程有独立空间,线程间暂时无法通信。线程之间也是独立的。
## 并发和并行
并发 是指多个程序抢占同一个CPU资源
并行 有多个cpu 每个cpu只负责一件事情 没有发生抢占现象
## 多线程特点
1. 随机性 操作系统的程序执行权,会交给CPU ,CPU我们控制不了,全部由操作系统调度
2. 线程状态
新建状态 , 可运行状态 ,运行状态 ,终止状态, 阻塞状态
## 多线程编程 ---继承Thread类
1. 创建对象
Thread(); 分配新的线程对象
Thread(Runnable target);
Thread(Runnable target, String name);
Thread(String name);
2.常用方法
static Thread currentThread();
long getId();//返回该线程的标识符 (ID)
String getName(); 返回线程名称
void setName()设定名称
static void sleep(long millis)
void run()
void start() 开始执行线程
package cn.tedu.thread;
public class Test1_Thread {
public static void main(String[] args) {
Mythread target = new Mythread();
Mythread target2 = new Mythread();
target.start();
target2.start();
}
class Mythread extends Thread{
@Override
public void run(){
for (int i = 0; i < 10 ; i++) {
System.out.println(getName()+"="+getId()+"="+i);
}
}
}
多线程编程 2 实现Runnable接口
package cn.tedu.thread;
public class Test2_Runnable {
public static void main(String[] args) {
MyRunnable target =new MyRunnable();
Thread t1= new Thread(target,"aa");
Thread t2 = new Thread(target,"bb");
t1,start();
t2.start();
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20 ; i++) {
System.out.println(Thread.currentThread().getName() +"=="+i);
}
}
}
模拟售票 案例 (多线程安全性)
package cn.tedu.thread;
public class Test3_Tickts {
public static void main(String[] args) {
MyTickets t1 = new MyTickets();
MyTickets t2 = new MyTickets();
MyTickets t3 = new MyTickets();
MyTickets t4 = new MyTickets();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class MyTickets extends Thread {
static int tickets = 100;
@Override
public void run() {
while (true) {
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + ":" + tickets--);
} else {
break;
}
}
}
}
同步锁
--1、原理:是指给你的共享资源加锁。还是可以让多个线程操作共享资源,只不过哪个线程有钥匙,
拿着钥匙进来开锁使用共享资源,没有钥匙的线程等待。--同步的锁,
--2、同步和异步的区别:
--同步:是需要拿着钥匙开锁,同一时刻只能有一个线程操作共享资源,其他线程排队等待。
牺牲了效率,提高了安全。
--异步:是没有排队的现象,大家同时使用了共享资源。提高了效率,牺牲了数据安全。
--举例:可以看做是你使用教室的门这个共享资源的过程
--3、语法
synchronized(对象){ 需要同步的代码块 }
--4. 使用锁
- 多线程安全 是由于线程的随机访问和访问的延迟所导致
- 在多线程编程中 如果有共享资源 并且这条资源被多条语句操作 那么就存在安全隐患
- 锁的位置 : 要合适 不能太大 会影响效率 不能太小 相当于没锁住
- 锁的对象:要求多个线程之间 使用的是同一把锁
- 使用范围 :可以用在方法上 也可以用在代码块上
改造的售票案例
class MyTickets implements Runnable{
int tickets = 100;
Object obj = new Object();
@Override
public synchronized void run(){
while(true){
synchronized(this){
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ~ " + tickets--);
} else {
break;
}
}
}
}
}