1. 程式人生 > 其它 >Lamda表示式、執行緒停止,休眠,禮讓(yield),join,優先順序,守護(daemon)、同步、Lock、執行緒池

Lamda表示式、執行緒停止,休眠,禮讓(yield),join,優先順序,守護(daemon)、同步、Lock、執行緒池

Lamda表示式

(1)Functional Interface(函式式介面)

(2)函式式介面定義:(即介面只有一個方法)

·任何介面,如果只包含唯一一個抽象方法,則是一個函式式介面

·對於函式式介面,可以通過Lamda表示式建立函式式介面的物件

範例:(外部類)

package proxy;
// 介面
interface Ilike{
public void lambda();
}
// 1、外部類
class Like1 implements Ilike{
@Override
public void lambda() {
System.out.println("外部類");
}
}
public class StaticProxy{
public static void main(String[] args) {
Like1 like1=new Like1(); //外部類
like1.lambda(); //外部類
}
}

範例:(靜態內部類)

package proxy;
// 介面
interface Ilike{
public void lambda();
}

public class StaticProxy{
// 2、靜態內部類
static class Like1 implements Ilike{
@Override
public void lambda() {
System.out.println("靜態內部類");
}
}
public static void main(String[] args) {
Like1 like1=new Like1(); //靜態內部類
like1.lambda();//靜態內部類
}
}

範例:(區域性內部類)

package proxy;
// 介面
interface Ilike{
public void lambda();
}

public class StaticProxy{

public static void main(String[] args) {
// 2、區域性內部類
class Like1 implements Ilike{
@Override
public void lambda() {
System.out.println("區域性內部類");
}
}

Like1 like1=new Like1(); //區域性內部類
like1.lambda();//區域性內部類
}
}

範例:(匿名內部類)

package proxy;
// 介面
interface Ilike{
public void lambda();
}

public class StaticProxy{

public static void main(String[] args) {

Ilike like1=new Ilike() {
@Override
public void lambda() {
System.out.println("匿名內部類");
}
};
like1.lambda(); //匿名內部類
}
}

範例:(Lamda表示式)---無參

package proxy;
// 介面
interface Ilike{
public void lambda();
}
public class StaticProxy{
public static void main(String[] args) {

Ilike like=()->{
System.out.println("Lamda表示式");
};
like.lambda(); //Lamda表示式
}
}

範例:(Lamda表示式)---有參

package proxy;
// 介面
interface Ilike{
public void lambda(int a);
}

public class StaticProxy{

public static void main(String[] args) {

Ilike like=(int a)->{
System.out.println("Lamda表示式"+a);
};
like.lambda(10); //Lamda表示式 10
}
}

執行緒停止

(1)建議執行緒正常停止----->利用次數

(2)建議使用標誌位---->設定一個標誌位(true/false)

(3)不要用stop或者destroy等過時或JDK不建議用的方法

執行緒方法

方法說明
setPriority(int newPriority) 更改執行緒的優先順序
static void sleep(long millis) 在指定的毫秒數內讓當前正在執行的執行緒休眠
void join() 等待該執行緒終止
static void yield() 暫停當前正在執行的執行緒物件,並執行其他執行緒
void interrupt() 中斷執行緒,不建議使用
boolean isAlive() 測試執行緒是否處於活動狀態

範例:(停止執行緒)

package collection;

public class Demo4 implements Runnable{
private boolean flag=true;
@Override
public void run() {
while (flag) {
System.out.println("輸出");
}
}

public void stop(){
this.flag=false;
}
public static void main(String[] args) {
Demo4 d4=new Demo4();
new Thread(d4).start();

for (int i = 0; i <50 ; i++) {
System.out.println("main"+i +" ");
if(i==30){
d4.stop();
System.out.println("執行緒停止了");
}
}
}
}

執行緒休眠

(1)sleep存在異常InterruptedException

(2)sleep可以模擬網路延時,倒計時等

(3)每個物件都有一個鎖,sleep不會釋放鎖

範例:(模擬倒計時)
package collection;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo5 {
public static void main(String[] args) throws InterruptedException {
Date date=new Date(System.currentTimeMillis());
// 獲取當前系統的時間
while (true){
Thread.sleep(1000); // 延時1秒
System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));
date=new Date(System.currentTimeMillis());
//(重新獲取) 更新當前系統的時間
}
}
}

執行緒禮讓yield

(1)執行緒禮讓,即讓當前正在執行的執行緒暫停,但不阻塞

(2)將執行緒從執行狀態轉為就緒狀態

(3)讓cpu重新排程,禮讓不一定成功,看cpu心情

package collection;
class MyYield implements Runnable{

@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"開始");
Thread.yield(); //禮讓
System.out.println(Thread.currentThread().getName()+"停止");
}
}

public class Demo6 {
public static void main(String[] args) {
MyYield my=new MyYield();

new Thread(my,"a").start();
new Thread(my,"b").start();
/*
不禮讓,則開始-結束為一對出現
a開始
a停止
b開始
b停止
*/
/*
禮讓,則開始-結束不為一對出現(也可能一對出現,可能禮讓不成功)
a開始
a停止
b開始
b停止
*/
}
}

join

(1)join合併執行緒,待此執行緒執行完成後,再執行其他執行緒,其他執行緒阻塞(可以理解為插隊)

package collection;
public class Demo7 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 90; i++) {
System.out.println("執行緒vip來了");
}
}

public static void main(String[] args) throws InterruptedException {
// 啟動執行緒
Demo7 d7=new Demo7();
Thread thread=new Thread(d7);
thread.start();

// 主執行緒
for (int i = 0; i < 100; i++) {
if (i==90){
thread.join(); // 插隊
}
System.out.println("main"+i);
}
}
}

執行緒中斷或結束,一旦進行死亡狀態,就不能再次啟動

執行緒優先順序

(1)執行緒的優先順序用數字表示,範圍1-10,大則優先順序高

(2)設定優先順序:setPriority(),獲取優先順序:getPriority()

(3)優先順序的設定要在start()排程前

(4)優先順序低只是意味著獲得排程的概率低,並不是優先順序低就不會被呼叫

範例:(設定優先順序)
package collection;
public class Demo7 implements Runnable {
@Override
public void run() {
System.out.println("Thread "+Thread.currentThread().getName()+"----->"+Thread.currentThread().getPriority());
}
public static void main(String[] args) throws InterruptedException {
Demo7 d1=new Demo7();
Thread t1=new Thread(d1,"t1");
Thread t2=new Thread(d1,"t2");
Thread t3=new Thread(d1,"t3");
Thread t4=new Thread(d1,"t4");
t1.setPriority(1); // 設定優先順序
t1 .start(); // 啟動執行緒
t2.setPriority(4); // 設定優先順序
t2 .start();
t3.setPriority(7); // 設定優先順序
t3 .start();
t4.setPriority(10); // 設定優先順序
t4 .start();
// 主執行緒,預設優先順序
System.out.println("main執行緒");
}
}

守護(daemon)執行緒

(1)執行緒分為使用者執行緒和守護執行緒

(2)虛擬機器必須確保使用者執行緒執行完畢

(3)虛擬不有等待守護執行緒執行完畢

範例:(守護執行緒)
package collection;

public class TextDaemon {
public static void main(String[] args) {
God god=new God();
You you=new You();
Thread thread=new Thread(god);
//設定守護執行緒,setDaemon()預設為false,正常的執行緒是使用者執行緒,
thread.setDaemon(true);
thread.start();

new Thread(you).start();
}
}
// 上帝
class God implements Runnable{
@Override
public void run() {
while(true){
System.out.println("上帝一直守護著你");
}
}
}
// 你
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 3650; i++) {
System.out.println("你活了"+i+"天");
}
System.out.println("====================Godbye==================");
}
}

執行緒同步

多個執行緒操作同一個資源 併發:同一個物件被多個執行緒同時操作

範例:(同步方法)
package collection;

public class Demo10 {
public static void main(String[] args) {
LLock ck=new LLock();
new Thread(ck).start();
new Thread(ck).start();
new Thread(ck).start();
}
}

class LLock implements Runnable{
private int licket=10;

@Override
public synchronized void run() {
while (true){
if (licket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(licket--);
}else {
break;
}
}

}
}

Lock(鎖)

(1)使用ReentrantLock類實現Lock,可以顯式加鎖、解放鎖

ReentrantLock可重用鎖

synchronized與Lock

synchronizedlock
隱式鎖(出了作用域自動釋放) 顯式鎖(手動開啟和關閉鎖)
有程式碼鎖和方法鎖 只有程式碼鎖

優先使用順序:

Lock > 同步程式碼塊(已經進入了方法體,分配了相應資源) > 同步方法(在方法體之外)

範例:(同步程式碼塊)
package collection;
import java.util.concurrent.locks.ReentrantLock;
public class Demo10 {
public static void main(String[] args) {
LLock ck=new LLock();
new Thread(ck).start();
new Thread(ck).start();
new Thread(ck).start();
}
}

class LLock implements Runnable{
private int licket=10;
// 定義lock 鎖
private final ReentrantLock lock=new ReentrantLock();

@Override
public void run() {
while (true){
try{
lock.lock(); // 加鎖
if (licket>0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(licket--);
}else{
break;
}
}finally {
lock.unlock(); // 解鎖
}
}
}
}

範例:(同步)---生產者消費者模型
package text;
public class Text {

public static void main(String[] args) {
M m=new M();
new P(m).start();
new C(m).start();
}
}

// 演員
class P extends Thread{
private M m;
public P(M m){
this.m=m;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if(i%2==0){
this.m.play("aaa");
}else {
this.m.play("bbb");
}
}
}
}

// 觀眾
class C extends Thread{
private M m;
public C(M m){
this.m=m;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
this.m.watcher();
}
}
}

// 節目
class M{
private String name;
boolean flag=true;

public synchronized void play(String name){
if(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("========表演"+name);
// 通知歡眾觀看
this.notify();
this.name=name;
this.flag=!this.flag;
}

public synchronized void watcher(){
if (flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("觀看"+name);
// 通知演員表演
this.notify();
this.flag=!this.flag;
}
}

執行緒池

(1)真正執行緒池介面:ExecutorService。常見子類ThreadPoolExecutor

(2)Executors:工具類、執行緒池的工廠類,用於建立並返回不同型別的執行緒池

// 建立服務,建立執行緒池,newFixedThreadPool , 引數為:執行緒池大小

ExecutorService service=Executors.newFixedThreadPool(10);

範例:
package text;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Text1 {
public static void main(String[] args) {
// 建立服務,建立執行緒池,newFixedThreadPool , 引數為:執行緒池大小
ExecutorService service=Executors.newFixedThreadPool(10);

// 執行
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());

// 關閉連結
service.shutdown();

// pool-1-thread-1
// pool-1-thread-2
// pool-1-thread-3
// pool-1-thread-4
}
}

class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}