一.多线程
a.大致内容
1.进程:在内存中执行的应用程序
2.线程:是进程中最小执行单元
线程作用:负责当前进程中程序的运行,一个进程至少有一个线程,一个进程中还可以有多个线程,简称:多线程
3.使用场景
软件中耗时操作->拷贝大文件,加载大量资源
所有聊天
后台服务器
一个线程可以干一件事,我们就可以同时干多件事,提高cpu利用率
b.并发和并行
1.并行:在同一时刻,有多个执行在多个cpu上同时惊进行
2.并发:在同一时刻,有多个指令在单个cpu上交替执行
detail:
1.之前cpu是单核的,但是执行多个程序的时候好像是在同时执行,原因是cpu在多个线程之间做高速切换
2.现在cpu是多核多线程的了,比如2核4线程,cpu可以同时运行4个线程,多了就要切换,所以现在cpu执行并发和并行都存在
c.CPU调度
1.分时调度:指的是让每个线程轮流获取cpu使用权,并且平均分配每个线程占用cpu的时间片
2.抢占模式多个线程轮流抢cpu使用权,优先级高抢到几率大,java用的这种
d.实现thread
1.extends Thread
1.定义一个类,继承tread
2.重写run方法设置线程任务(具体干的事,执行代码)
3.创建自定义线程类对象
4.调用tread中的start方法,开启线程
java
package tread_class;
public class thread extends Thread{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
}
}
java
package tread_class;
public class test01 {
public static void main(String[] args) {
//创建线程对象
thread thread = new thread();
//调用start
for (int i = 0; i < 10; i++) {
System.out.println("main"+i);
}
thread.start();
}
}
e.运行原理
f.常用方法
run()->设置线程任务
getname()->获取线程名字
setname()->设置名字
currentThread()->获取正在执行的线程对象
sleep()->线程睡眠,超时后自动醒来
java
package tread_class;
public class thread01 extends Thread{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
//sleep睡觉
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(i);
}
}
}
java
package tread_class;
public class test02 {
public static void main(String[] args) {
thread01 thread01 = new thread01();
//设置名字
thread01.setName("111");
thread01.start();
//获取
System.out.println(thread01.getName());
for (int i = 0; i <10 ; i++) {
//获取当前线程
System.out.println(Thread.currentThread().getName()+i);
}
}
}
问题:为啥在重写的run方法中有异常只能try不能throws
原因:继承的thread中的run方法中没有抛异常,所以子类重写后不能抛只能try
g.其他方法
setPriority(int newPriority)->设置线程优先级,不是一定是最先抢到的,提高几率
gettPriority->获取优先级
setDeamon()->守护线程->当非守护线程执行完毕,守护线程就要结束,但是守护线程也不会立马结束,系统返回需要时间
yield()->礼让线程
join()->插队线程,插入某线程之前
java
package mythread;
public class thread_02 extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("thread"+currentThread().getName()+"........"+i);
}
}
}
java
package mythread;
public class test01 {
public static void main(String[] args) {
thread_02 thread02 = new thread_02();
thread02.setName("t1");
thread_02 thread03 = new thread_02();
thread03.setName("t2");
System.out.println(thread02.getPriority());
System.out.println(thread03.getPriority());
thread03.setPriority(1);
thread02.setPriority(10);
thread03.start();
thread02.start();
}
}
java
package mythread.protest;
public class mythread02 extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(currentThread().getName()+"/"+i);
}
}
}
package mythread.protest;
public class mythread01 extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"......."+i);
}
}
}
package mythread.protest;
public class mythread02 extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(currentThread().getName()+"/"+i);
}
}
}
g.1第二种方式实现Runnable接口
1.创建类实现runnabe接口
java
package mythread.runnable;
public class myrunable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"......"+i);
}
}
}
2.重写run方法,设置线程任务
3.利用thread构造方法:Thread(Runnable target)
java
package mythread.runnable;
public class Test01 {
public static void main(String[] args) {
myrunable myrunable = new myrunable();
Thread t1=new Thread(myrunable);
t1.start();
}
}
4.调用start
f两种线程区别
继承只支持单继承
Runnable:没有继承局限性,可以多继承
h匿名内部类创建多线程
匿名内部类回顾
1.new接口()/抽象类()
{
重写方法
}.重写方法();
2.接口名/类名 对象名=new 接口/抽象类(){
重写方法
}
对象名.方法();
java
public class test01 {
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
for (int i=0;i<10;i++)
{
System.out.println(Thread.currentThread().getName()+i);
}
}
}.start();
}
}
m安全
java
public class mytickt implements Runnable{
int tickt=100;
@Override
public void run() {
while (true) {
if (tickt > 0) {
System.out.println(Thread.currentThread().getName() + "买到票了" + tickt + "票");
tickt--;
}
}
}
}
public class Test02 {
public static void main(String[] args) {
mytickt mytickt = new mytickt();
Thread t1=new Thread(mytickt,"赵四");
Thread t2=new Thread(mytickt,"张三");
Thread t3=new Thread(mytickt,"王五");
t1.start();
t2.start();
t3.start();
}
}
解决方法一(上锁)(使用同步代码块)
- 1.格式
- synchronized(任意对象){
线程可能出现不安全}
- synchronized(任意对象){
- 2.任意对象:即是锁对象
- 3.执行:
- 抢到锁就执行,没有就等待
java
package mythread.change_security;
public class mytickt implements Runnable{
int tickt=100;
//任意new一个对象
Object obj =new Object();
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (obj)
{
if (tickt > 0) {
System.out.println(Thread.currentThread().getName() + "买到票了" + tickt + "票");
tickt--;
}
}
}
}
}
public class Test02 {
public static void main(String[] args) {
mytickt mytickt = new mytickt();
Thread t1=new Thread(mytickt,"张三");
Thread t2=new Thread(mytickt,"赵四");
Thread t3=new Thread(mytickt,"王五");
t1.start();
t2.start();
t3.start();
}
}
解决方法二
非静态
-
在Runnale接口类中写一个单独的方法
-
默认锁对象是this
java
package mythread.change_security;
public class mytickt implements Runnable{
static int tickt=100;
//任意new一个对象
Object obj =new Object();
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
method();
}
}
public static void method()
{
if (tickt > 0) {
System.out.println(Thread.currentThread().getName() + "买到票了" + tickt + "票");
tickt--;
}
}
}
静态
1.格式:
修饰符 static synchronized 返回值类型 方法名(参数){
方法体
}
return 结果
2.默认值:class对象
h死锁
静态
1.格式:
修饰符 static synchronized 返回值类型 方法名(参数){
方法体
}
return 结果
2.默认值:class对象
g生命周期
1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
- 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。 - 阻塞(BLOCKED):表示线程阻塞于锁。
- 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
- 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
- 终止(TERMINATED):表示该线程已经执行完毕。
————————————————
原文链接:更多请点击