Java多线程
2021-03-05 05:29
标签:rac 顺序 cpu start lock 控制 setdaemon version pack 1.为什么要重写run()方法? 因为run()方法是用来封装线程要执行的代码的。 2.run()方法和start()方法的区别? 直接使用run()方法并不是启动多线程,使用start()才是启动线程,然后由JVM调用此线程的run()方法。 提供一个静态方法获取当前线程名称: 线程有两种调度模型 线程的默认优先级是5,范围是1-10,仅仅表示获取CPU时间片的几率。 使当前正在执行的线程停留或者暂停执行指定的毫秒数 在run()方法内使用 当前线程调用join方法时,其余线程要等待当前线程执行完。 start之后就可以使用。 需要在start之前设置,否则会报出IllegalThreadStateException异常。 将当前线程标记为守护线程。当主线程执行完毕后,不会等守护线程结束,jvm会退出。线程会后续消失,不是立即消失。 在deamon线程中设置的子线程也是deamon 给当前线程添加中断标签,如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。 interrupt() 方法只是改变中断状态而已,它不会中断一个正在运行的线程。这一方法实际完成的是,给受阻塞的线程发出一个中断信号,这样受阻线程就得以退出阻塞的状态。 更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,此时调用该线程的interrupt()方法,那么该线程将抛出一个 InterruptedException中断异常(该线程必须事先预备好处理此异常),从而提早地终结被阻塞状态。如果线程没有被阻塞,这时调用 interrupt()将不起作用,直到执行到wait(),sleep(),join()时,才马上会抛出 InterruptedException。 让当前正在执行的线程暂停一段时间,并进入阻塞状态,则可以通过调用Thread类的静态sleep()方法来实现。当前线程调用sleep()方法进入阻塞状态后,在其睡眠时间内,该线程不会获得执行的机会,而其它任何优先级的线程都可以得到执行的机会,即使系统中没有其它可执行的线程,处于sleep()的线程也不会执行,sleep()是用来暂停线程的执行。 yield()方法是一个和sleep()方法有点相似的方法,它也是Thread类提供的一个静态方法。可以让当前正在执行的线程暂停,但它不会阻塞该线程,只是将该线程转入就绪状态。yeild()只是让当前线程暂停一下,让系统的线程调度器重新调度一次,完全可能的情况是:当某个线程调用了yield()线程暂停之后,线程调度器又将其调度出来重新执行。 用实现Runnable接口的子类对象传入Thread对象中 好处: 1.实现接口不影响继承其他类。 2.将Runable的实现类当作参数可传入多个Thread,可看作同一个资源由多个线程使用。 卖票案例: 三个窗口买100张票,在run方法中使用sleep,由于线程堵塞性和随机性,导致会出现连续100张出票情况,然后变成97。 以上情况就是非线程安全,线程安全就是在多线程过程中,不管怎么调用方法,都不会出现上面的情况。 数据安全 以上三条同时满足会出现数据安全问题。 怎么保护数据呢? 将synchronized关键词加上方法上 修饰符 synchronized 返回值类型 方法名(){} 同步方法锁什么? this 修饰符 static synchronized 返回值类型 方法名(){} 静态方法跟类加载有关,this代表的是当前对象。所以静态同步方法应该锁类名.class Collections JDK5以后的更方便的同步线程API,同步代码块和同步方法看见哪里锁对象和解锁并不是很明显。 Lock是一个接口,ReentrantLock是Lock的实现类。 线程中互相等待资源的现象 1.更改加锁的顺序 2.再加一把锁 生产者与消费者模型是经典的多线程协作模式。 生产线程---->共享数据
sleep是Thread 中的静态方法,wait是Object类中的方法。 sleep不会改变当前锁对象的状态,wait会立即释放锁。 Executors Java多线程 标签:rac 顺序 cpu start lock 控制 setdaemon version pack 原文地址:https://www.cnblogs.com/jiangsonglin/p/14332693.htmlJava多线程
多线程的实现1
设置和获取线程名称
Thread.currentThread().getName();
线程调度
线程控制
static void sleep(long millis)
void join()
void setDaemon(boolean on)
void interrupt();
static void yield();
线程睡眠(sleep)
线程让步(yield)
当某个线程调用了yield()方法暂停之后,只有优先级与当前线程相同,或者优先级比当前线程更高的处于就绪状态的线程才会获得执行机会。线程的生命周期
多线程的实现2
new Thread(new Runnable(){
@Overide
public void run(){
....
}
}).start();
package com.jiang.test.strings;
import static java.lang.Thread.sleep;
/**
* @version 1.0
* @Description:
* @author: jiangsonglin
* @date: 2021/1/20 19:58
*/
public class Demo {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
Thread m1 = new Thread(myThread, "窗口一");
Thread m2 = new Thread(myThread, "窗口二");
Thread m3 = new Thread(myThread, "窗口三");
m1.start();
m2.start();
m3.start();
}
}
class MyThread implements Runnable {
int ticks=100;
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (this.ticks > 0) {
System.out.println(Thread.currentThread().getName() + "正在出售" + ticks + "张票");
ticks--;
}
}
}
}
线程安全
线程同步
同步代码块
synchronized(任意对象){
多条语句操作共享数据的代码
}
class xxx implements Runable{
Object ob = new Object();//任意对象
@Overide
public void run(){
synchronized(ob){
....
}
}
}
同步方法
静态同步方法
Lock
void lock();
void unlock();
class xxx implements Runable{
Lock lock = new ReentrantLock();
@Overide
public void run(){
try{
lock.lock();
....
}finally{
lock.unlock();
}
}
}
死锁
生产者与消费者
void wait();
//在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
void notify();
//唤醒在此对象监视器(锁对象)上等待的单个线程。
void notifyAll();
//唤醒在此对象监视器上等待的所有线程。
sleep与wait
线程池
CPU ,则目标并行级别被设置为 ,也就是相当于为前 个方法传入 作为参数定时任务
上一篇:线程池的使用