伺服器分類介紹以及伺服器作業系統安裝
阿新 • • 發佈:2022-03-17
建立執行緒
1 Thread
//繼承Thread類,重寫run()方法,!!!!使用start開啟執行緒 //執行緒呼叫後不會馬上啟用,由CPU決定 public class Myrun extends Thread() { public void run() { System.out.println("111"); } } public static void main (String[] args) { Myrun my = new Myrun(); my.start();//啟用執行緒 //my.run();是呼叫方法,不是啟用的執行緒,不會有多個執行緒同時執行 }
2 runnable
//實現Runnable介面,重寫run()方法,
public class Myrun implements Runnable()
{
public void run()
{
System.out.println("111");
}
}
public static void main (String[] args)
{
Myrun my = new Myrun();
Thread thread = new thread(my);
thread.start();
}
多個執行緒操作同一個物件(併發)
public class Trainticket implements Runnable { private int ticketnums = 10; public void run() { while (ticketnums > 0) { System.out.println(Thread.currentThread().getName() + "--> get " + ticketnums); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } ticketnums--; } } public static void main(String[] args) { Trainticket ticket = new Trainticket(); new Thread(ticket, "1").start();//1是執行緒的名字 new Thread(ticket, "2").start(); } }
- 但是多個執行緒操作同一個物件可能導致資料紊亂,例如“1” “2”拿到相同序號的票,執行緒不安全。
Lamda 表示式
-
函式式介面:任何介面,如果只包含一種抽象方法,那麼它就是一個函式式介面。而對於函式式介面,可以通通過lambda表示式來建立該介面。
public class Ilike { Like like = (/*如果有引數就填寫引數*/)->{System.out.println("1111");}; //like = 引數->{System.out.println("1111");}; //like = 引數->System.out.println("1111");多行程式碼不可簡化掉{},且多個引數時()不可省略 } like.lambda; interface Like { void lambda(); }
多執行緒的操作
停止
- 推薦執行緒自己停下,使用標誌位flag,當flag為flase時停止
public class Myrun extends Thread()
{
private Boolean flag = true;
public void run()
{
int i;
while(flag){
System.out.println("myrun"+i);
}
}
public void stop()
{
this.flag = false;
}
}
public static void main (String[] args)
{
Myrun my = new Myrun();
Thread(my).start();
int i;
for(i=0;i<1000;i++)
{
if(i == 900)
{
my.stop;
System.out.println("stop");
}
System.out.println(i);
}
}
休眠
- 休眠的單位是毫秒
- 每個物件都有一個鎖,sleep不會釋放鎖
禮讓
-
禮讓執行緒,讓當前正在執行的執行緒暫停,但不阻塞。
-
讓cpu重新排程,但是禮讓不一定成功
-
將執行緒從執行狀態轉為就緒狀態
class myrun implements Runnable { public void run() { System.out.println(/*Threadname+*/"start"); Thread.yield(); System.out.println(/*Threadname+*/"end"); } }
Join
- Join合併執行緒,待此執行緒執行完成之後,再執行其他執行緒,其他執行緒阻塞(插隊執行
thread.join
public class Join implements Runnable{
@Override
public void run() {
for (int i = 0; i < 500; i++) {
System.out.println("VIP:"+i);
}
}
public static void main(String[] args) throws InterruptedException {
Join j = new Join();
Thread thread = new Thread(j);
thread.start();
for (int i = 0; i < 1000; i++) {
if(i == 500)
thread.join();
System.out.println("main:"+i);
}
}
}
檢視狀態
-
thread.state
public class State{ public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(()->{ for (int i = 0; i < 10; i++) { try { Thread.sleep(100);//因為有休眠所以存在WAITING } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(i); } }); Thread.State state = thread.getState(); System.out.println(state);// NEW thread.start(); state=thread.getState(); System.out.println(state);//Run while (state!=Thread.State.TERMINATED) { Thread.sleep(100); state = thread.getState(); System.out.println(state); } } }
-
執行緒的狀態
- NEW: 尚未啟動的狀態
- RUNNABLE 執行的執行緒
- BLOCKED 被阻塞等待監視器鎖定
- WAITING 等待另外一個執行緒執行特定動作
- TIMED_WAITING 等待另外一個執行緒執行動作達到指定等待時間
- TERMINATED 已經退出的執行緒
優先順序
-
執行緒的優先順序用1-10表示,數字大的優先順序高
-
可以通過
getPriority()
獲得優先順序,setPriority(int a)
改變優先順序//測試優先順序 public class Priority { public static void main(String[] args) { System.out.println(Thread.currentThread().getName()+"---->"+Thread.currentThread().getPriority()); Mypriority my = new Mypriority(); Thread t = new Thread(my,"0"); Thread t1 = new Thread(my,"1"); Thread t2 = new Thread(my,"2"); Thread t3 = new Thread(my,"3"); Thread t4 = new Thread(my,"4"); t1.setPriority(1); t2.setPriority(5); t3.setPriority(7); t4.setPriority(Thread.MAX_PRIORITY); t.start(); t1.start(); t2.start(); t3.start(); t4.start(); } } class Mypriority implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName()+"---->"+Thread.currentThread().getPriority()); } }
PS:跑出來可能和預想的不太一樣
併發
- 同一個物件被多個執行緒同時操作,例如搶票
- 利用鎖保證執行緒的安全‘
- 每個物件都擁有一把鎖
- sleep不會釋放鎖
- synchronize:鎖修改的變數
- 鎖塊 synchronize(obj){}
- 鎖類
CopyOnWriteArrayList<> 該類是執行緒安全的容器
死鎖
- 多個執行緒各自佔有一些共享資源,並且互相等待其他執行緒佔有的資源才能執行,而導致兩個或者多個執行緒都在等待對方釋放資源,都在停止執行。如果某一個同步塊同時擁有兩個以上物件的鎖,就可能發生死鎖。
- 產生死鎖的程式
public class DeadBlock {
public static void main(String[] args) {
Makeup m1 =new Makeup(0,"g1");
Makeup m2 = new Makeup(1,"g2");
m1.start();
m2.start();
}
}
class Lipstick
{
}
class Mirror
{
}
class Makeup extends Thread
{
//只有一份資源
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice;
String name;
Makeup(int choice,String name)
{
this.choice = choice;
this.name = name;
}
@Override
public void run() {
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void makeup() throws InterruptedException {
if(choice == 0)
{
synchronized (lipstick)
{
System.out.println(this.name+"獲得口紅");
Thread.sleep(1000);
synchronized (mirror)// 該部分
{
System.out.println(this.name+"獲得鏡子");
}
}
}
else
{
synchronized (mirror)
{
System.out.println(this.name+"獲得鏡子");
Thread.sleep(1000);
synchronized (lipstick)// 該部分
{
System.out.println(this.name+"獲得口紅");
}
}
}
}
}
修改後的正確執行(部分
if(choice == 0)
{
synchronized (lipstick)
{
System.out.println(this.name+"獲得口紅");
Thread.sleep(1000);
}//不能有兩個鎖,拿出釋放一個鎖
synchronized (mirror)
{
System.out.println(this.name+"獲得鏡子");
}
}
else
{
synchronized (mirror)
{
System.out.println(this.name+"獲得鏡子");
Thread.sleep(1000);
}
synchronized (lipstick)
{
System.out.println(this.name+"獲得口紅");
}
}
顯式鎖Lock
- 和synchronized相比,需要手動開啟和關閉鎖,只能鎖程式碼塊
- 效能較好一點
private final ReentrantLock lock = new ReentrantLock();
private void m()
{
try {
lock.lock();
//程式碼塊
}
finally {
lock.unlock();
}
}