最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

一、【Java】多线程与高并发

来源:博客园

一、启动多线程的三种方式


(资料图)

1、继承Thread 接口类 实现 run() 方法

static class MyThred extends Thread{ @Override public void run(){system.out.println("Hellow MyThread!"))}}

2、继承Runnable 接口类 实现 run() 方法

static class MyThred extends Runnable{ @Override public void run(){system.out.println("Hellow Run!"))}}

3、通过线程池也可以启动一起线程

Executors.newCachedThread

二、线程的 Sleep_Yield_Join基本 方法

1、Sleep()

1、Thread.sleep(500);

概念:CPU没有线程概念,当前线程在这休息500毫秒,这段时间其他线程去运行。运行完后再接着回来运行

2、Yield()

Thread.yield();

概念:运行过程中,yield() 一下,本质上是让出一下cpu,返回 “就绪” 状态,其他线程能不能抢到不管。

3、Join()

Thread t1=new Thread(()->{ for(int i=0;i<100;i++) { System.out.println("A"+i); try{ Thread.sleep(500); }catch(InterrupedException e){ e.printStackTrace(); } }});Thread t2=new Thread(()->{ try{ t1.join(); }catch(InterrupedException e){ e.printStackTrace(); }});

概念:当运行t2线程的时候调用一下t1线程,当t1线程完成以后,回来接着调用t2线程。

三、线程的状态

1、java里的线程状态迁移图,都是通过JVM来管理的,通过操作系统被管理。,通过线程的getState()获取状态。

1、NEW 状态:创建了,未调用初始状态。

2、Runnable 状态:交给操作系统执行(线程调度器)

2.1、Ready:就绪状态,在CPU的等待队列里,排着队,还没运行呢,

2.2、Running:正在运行的状态,正在CPU里运行中。

3、Teminated 状态:运行结束。

4、TimedWaiting:等待状态,Thread.sleep(time),o.wait(time),t.join(time),LockSupport.parkNanos(),LockSupport.partUntill(),会进入这个状态。

5、Waitig:等待状态,o.wait(), t.join() ,LockSupport.part(),会进去这个状态

6、Blocked:阻塞状态;进入到同步代码块,没有得到锁的时候。

四、高并发、sysnchronized 关键字

1、多个线程访问一个资源的时候,对这个资源加锁

private int count=10;private Object o=new Object();public void m(){ synchronized(o){//任何线程要想执行以下代码,必须先拿到o的锁 count--; System.out.println(Thread.currentThread().getName()+"count="+count); }}

每次new一个object很麻烦,可以锁当前对象 this

private int count=10;public void m(){ synchronized(this){ count--; System.out.println(Thread.currentThread().getName()+"count="+count); }}

可以简写成以下代码,一个 synchronized 方法

private int count=10;public synchronized void m(){//任何线程要想执行以下代码,必须先拿到o的锁 count--; System.out.println(Thread.currentThread().getName()+"count="+count);}

静态方法也可以

private int count=10;public synchronized static void m(){//这里等同于synchronized(T.class) count--; System.out.println(Thread.currentThread().getName()+"count="+count);}public static void mm(){ synchronized(T.class){ count--; }}

五、synchronized的底层实现

1、JDK早期 synchronized 是重量级的,要向系统申请锁,很慢

2、后来JDK(1.5)改进,锁升级,原来都是找操作系统申请锁,到后期对synchronized 做了一些改进,效率高不少。

例如:synchronized(object)的时候,只有一个线程访问,是不给他加锁的,只记录线程ID(偏向锁)。如果有线程争用,就升级为(自旋锁),自旋锁 如果一个线程 旋了 10次以后 还没得到锁,则升级为(系统锁)操作系统锁。

3、只能升级锁,不能降级,例如多个线程通过争用升级到(系统锁),线程数下去以后,不会降级!!!

5、加锁代码执行时间长的情况下,线程数比较多,使用系统锁(系统锁),加锁代码执行时间短,线程数少的情况下,使用(自旋锁)。

六、使用synchronized注意

1、不能使用String常量、Integer、Long 等基础数据类型。

2、synchronized 锁不住空对象,空对象没有markword。

关键词: 操作系统 的情况下 等待状态