河曲智叟 发表于 2024-9-7 07:13:12

Java基础 ——线程

多线程

并行和并发


[*] 需求:边打好汉联盟和边听音乐
[*] 问题:只能先后关系,并不能同时发生

[*]多进程或者多线程来办理

[*] 并行和并发:

[*] 并行:多件事变在同一时候发生
[*] 并发:多件事变在同一时间段发生,同一时间段多个程序同时运行

[*] 单个CPU:一个时间点只能执行一个程序,多个程序可以交替执行。
[*] 线程调理:多个线程以某个顺序执行
进程与线程


[*]进程:内存中的应用程序,每个进程有一块独立的内存空间,一个应用程序可以同时启用多个进程,有独立内存空间,至少有一个线程
[*]线程:进程中的执行任务单元,一个进程里面可以拥有多个线程,栈空间独立,堆内存共享
[*]多线程的优势:因为堆内存是共享的,以是内存的开销是不是较少。
[*]多线程具体运行谁人线程,取决于 CPU调理
[*]java 程序中最少有几个线程:

[*]主线程
[*]GC垃圾接纳线程

[*]线程的调理:JVM 接纳抢占式的调理方式,没有接纳分时概念,谁抢到谁执行。
[*]多线程的应用:

[*]抢票
[*]游戏
[*]多线程下载

[*]宽带带宽:以位(bit)计算的,下载速度以字节(byte),1字节=8位

[*]1024KB/s 代表 1M,下载速度,1024/8 128KB/s

多线程实现方式


[*] 继承 Thread 类

[*] 重写 run 方法
public class MusicDemo extends Thread{
    @Override
    public void run() {
      for (int i = 0; i < 10; i++) {
            System.out.println("听音乐:"+i);
      }
    }

}

[*] 启动线程,调用 start 方法
MusicDemo musicDemo = new MusicDemo();
musicDemo.start();

[*] 注意:不要去调用 run() 方法

[*] 实现 Runnable 接口

[*] 实现Runnable 接口,实现 Run 方法
public class PlayGame implements Runnable {
    @Override
    public void run() {
      for (int i = 0; i < 10; i++) {
            System.out.println("打游戏:" + i);
      }
    }
}

[*] 启动(先创建对象,再创建 Thread 对象通过构造器获得线程对象)
PlayGame playGame = new PlayGame();
Thread thread = new Thread(playGame);
thread.start();


[*] 使用匿名内部类来创建线程(只适用于只使用一次的方式)
new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                  System.out.println("统计人头数:" + i);
                }
            }
      }).start();

线程的调理


[*] 线程控制操作:Thread.sleep(1000L);
[*] 线程合并(团结线程):

[*]join方法(操作线程先执行完之后,等候线程才执行)

[*] 保卫线程:GC 使用

[*]目的:为别的线程服务的—GC—
[*]特点:主线程竣事,保卫线程就竣事
[*]创建线程:默认是前台线程
[*]获取保卫线程thread.setDaemon(true),必须再 start() 方法之前

[*] 获取当前线程及其名称

[*]Thread t = Thread.currentThread();
[*]t.getName();

[*] 线程设置优先级

[*] 注意:优先级高,只不过是获取执行机会更大(取决于CPU调理)
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;

/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;

/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;


[*] 线程的让位:

[*]yield 方法:当前线程对象去提示CPU调理器本身愿意让出CPU资源(但是调理器可以忽略你的哀求)
[*]sleep 和 yield 方法的区别

[*]都能使当前处于运行状态的线程临时放弃 cpu 把机会给别的线程
[*]sleep 方法给别的线程运行机会,但是不考虑别的线程的优先级,yield 只会给相同优先级,或者更高优先级的线程运行机会
[*]调用 sleep 方法之后,线程进入计时等候状态,yield 进入停当状态


线程同步


[*] 需求:猴子(3个 A B C)吃香蕉30个,使用多线程的方式实现

[*] 继承 Thread 类的方式

[*] 同一个编号的香蕉被多个猴子吃
public class MonkeyDemo extends Thread {
    private int num = 30;//香蕉总数
    @Override
    public void run() {
      for (int i = 0; i < 30; i++) {
            if (num > 0) {
                System.out.println(super.getName() + "吃了编号为:" + num-- + "的香蕉");
            }
      }
    }
}


MonkeyDemo monkeyA = new MonkeyDemo();
monkeyA.setName("A");

MonkeyDemo monkeyB = new MonkeyDemo();
monkeyB.setName("B");

MonkeyDemo monkeyC = new MonkeyDemo();
monkeyC.setName("C");

monkeyA.start();
monkeyB.start();
monkeyC.start();}}


[*] 实现 Runnable 接口

[*]是否可以共享同一个资源的缘故原由,实现方式可以做到(当有网络耽误的时候,也不可以做到)
public class MonkeyRunnable implements Runnable{

    private int num = 30;
    @Override
    public void run() {
      for (int i = 0; i < 30; i++) {
            if (num > 0) {
                System.out.println(Thread.currentThread().getName() + "吃了编号为:" + num-- + "的香蕉");
            }
      }
    }
}

MonkeyRunnable runnable = new MonkeyRunnable();

new Thread(runnable,"A").start();
new Thread(runnable,"B").start();
new Thread(runnable,"C").start();


[*] 办理多个猴子不能同时吃到同一个香蕉的案例

[*] 同步代码块

[*] 语法
[*] 非静态
[*] 同步锁是谁?

[*]非静态的来说,同步锁就是 this
[*]静态的来说,类的字节对象(MonkeyRunnable.class)
synchronized(同步锁){
}

[*] 为了保证每个线程都可以或许正常执行,原子操作,一般的,把当前并发访问的共同资源作为同步监听对象
[*] 任何时候,只能运行一个线程拥有同步锁,谁拿到谁执行,别的的等候
[*] 不要使用同步锁去修饰 run 方法,修饰之后,某一个线程执行完了别的的才可以执行

[*] 同步方法
synchronized public void eat() {
    //业务逻辑
}

[*] 锁机制(Lock):
Lock lock = new ReentrantLock();
//上锁
lock.lock();
      if (num > 0) {
            System.out.println(Thread.currentThread().getName() + "吃了编号为:" + num-- + "的香蕉");
      }
//解锁
lock.unlock();


[*] 同步代码块,同步方法,同步锁如何选用?

[*]只管淘汰锁的作用域(Synchronized)
[*]发起使用锁机制(很好的去控制锁的作用范围,性能更高)


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Java基础 ——线程