Java進階總結——線程
/**
* java中啓動進程的兩種方式
* 1.RunTime,運行時類
* 2.ProcessBuilder類
* */
package day24.process;
import java.io.IOException;
public class ProcessDemo {
public static void main(String[] args) throws IOException {
/*//1通過運行時類
Runtime time=Runtime.getRuntime();
//執行要打開的進程
time.exec("notepad");
time.exec("D:\\TSBrowserDownloads\\cmder\\Cmder.exe");
*/
//2通過進程生成器啓動進程
ProcessBuilder builder=new ProcessBuilder("notepad");
//啓動進程
builder.start();
}
}
運行結果:
啓動應用程序!
/**
* ThreadDemo繼承了Thread
* 你什麼該類就是一個線程類
* 必須在子類中重寫run方法
* run方法是線程體
* * */
package day24.thread;
public class ThreadDemo extends Thread{
@Override
public void run() {
// 線程體
try {
Thread.sleep(1000);//休眠1s
} catch (InterruptedException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
//獲取線程名稱
System.out.println(Thread.currentThread().getName());
}
public static void method() {
//獲取當前線程
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
// 1.獲取當前線程
Thread th=Thread.currentThread();
//2.查看當前線程
System.out.println("名稱:"+th.getName());//名稱
System.out.println("狀態:"+th.getState());//狀態
System.out.println("ID:"+th.getId());//ID
System.out.println("優先級:"+th.getPriority());//優先級
method();
//3.創建一個子線程,啓動了一個線程,其實做了一個異步操作
ThreadDemo th1=new ThreadDemo();
//給線程命名
th1.setName("尊");
//啓動線程 不能直接調用run方法,必須通過start來調用
th1.start();
System.out.println("執行完畢!");
}
}
輸出結果:
/**
* ThreadDemo1實現Runnable這個接口
* ThreadDemo1不是線程類
* */
package day24.thread;
public class ThreadDemo1 implements Runnable{
@Override
public void run() {
// 線程體
System.out.println("線程名稱:"+Thread.currentThread().getName());
}
public static void main(String[] args) {
//創建一個ThreadDemo1的實例
ThreadDemo1 demo=new ThreadDemo1();
//創建一個線程對象,執行demo對象
Thread th=new Thread(demo,"qq");
//啓動線程
th.start();
//再次啓動一個線程
Thread th1=new Thread(demo,"ww");
th1.start();
}
}
package day25.thread;
public class ThreadDemo extends Thread{
@Override
public void run() {
for (int i = 0; i < 120; i++) {
System.out.println(Thread.currentThread().getName()+"\t優先級:"+Thread.currentThread().getPriority());
}
}
public static void main(String[] args) {
//初始三個線程
ThreadDemo demo=new ThreadDemo();
ThreadDemo demo1=new ThreadDemo();
ThreadDemo demo2=new ThreadDemo();
//命名
demo.setName("A");
demo1.setName("B");
demo2.setName("C");
//設置優先級1-5 默認是5
demo.setPriority(MIN_PRIORITY);
demo1.setPriority(MAX_PRIORITY);
//啓動
demo.start();
demo1.start();
demo2.start();
}
}
輸出結果:
package day25.thread;
public class ThreadDemo2 extends Thread{
@Override
public void run() {
System.out.println("運行狀態:"+Thread.currentThread().getState()+"\t激活:"+Thread.currentThread().isAlive());
}
@SuppressWarnings("static-access")
public static void main(String[] args) throws InterruptedException {
//初始化對象
ThreadDemo2 demo2=new ThreadDemo2();
System.out.println("創建狀態:"+demo2.getState()+"\t\t激活:"+demo2.isAlive());
//啓動線程
demo2.start();
System.out.println("啓動狀態:"+demo2.getState()+"\t激活:"+demo2.isAlive());
demo2.sleep(2000);
System.out.println("完畢狀態:"+demo2.getState()+"\t激活:"+demo2.isAlive());
}
}
輸出結果:
package day25.thread;
public class ThreadDemo1 extends Thread{
@Override
public void run() {
try {
System.out.println("生日快樂");
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
System.out.println("七夕快樂!");
}
public static void main(String[] args) throws InterruptedException {
// 初始化對象
ThreadDemo1 demo1=new ThreadDemo1();
//啓動線程
demo1.start();
//合併線程,demo1和主線程合併
//demo1.join();//join在start之後使用
//主線程執行方法
for (int i = 0; i < 10; i++) {
Thread.sleep(200);
if (i==3) {
demo1.join();
}
System.out.println("i====="+i);
}
}
}
輸出結果:
package day25.thread;
public class ThreadDemo3 implements Runnable{
@SuppressWarnings("static-access")
@Override
public void run() {
for (int i = 0; i < 6; i++) {
if (i==3) {
//禮讓線程
Thread.currentThread().yield();
System.out.println("禮讓");
}
System.out.println("i=="+i+" "+Thread.currentThread().getName());
}
}
public static void main(String[] args) {
// 初始化對象
ThreadDemo3 demo3=new ThreadDemo3();
//創建線程
Thread th1=new Thread(demo3,"qq");
Thread th2=new Thread(demo3,"rr");
Thread th3=new Thread(demo3,"uu");
//啓動線程
th1.start();
th2.start();
th3.start();
}
}
輸出結果:
package day25.thread;
public class ThreadDaemonDemo extends Thread{
@Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("七夕節快樂");
}
}
public static void main(String[] args) throws InterruptedException {
//創建對象
ThreadDaemonDemo demo=new ThreadDaemonDemo();
//把當前線程設爲守護線程,需要在啓動之前設置
demo.setDaemon(true);
//啓動線程
demo.start();
System.out.println("不快樂!");
Thread.sleep(3000);
System.out.println("喝酒");
}
}
輸出結果:
/**
* synchronized修飾符
* 可以修飾方法,鎖住的是當前對象this
* 可以修飾代碼塊
* 同步的意思
* */
package day25.thread;
public class AppleDemo implements Runnable {
//蘋果數量
private int count=50;
private static Object obj=new Object();
//修飾方法修飾的是this對象
public synchronized void method(){
if (count>0) {
System.out.println(Thread.currentThread().getName()+"1吃了第"+count+"個蘋果");
count--;
}
}
public void method1() {
synchronized (obj) {//同步代碼塊,作用域精確
if (count>0) {
System.out.println(Thread.currentThread().getName()+"2吃了第"+count+"個蘋果");
count--;
}
}
}
@Override
public void run() {
// 吃蘋果
for (int i = 0; i < 50; i++) {
//method();
method1();
}
}
public static void main(String[] args) {
// 初始化對象
AppleDemo demo=new AppleDemo();
//創建線程,啓動線程
Thread th1=new Thread(demo,"A");
th1.start();
Thread th2=new Thread(demo,"B");
th2.start();
Thread th3=new Thread(demo,"C");
th3.start();
}
}
輸出結果:
package day25.thread;
import java.util.concurrent.locks.ReentrantLock;
public class AppleLock implements Runnable {
private int count=50;
//創建一個互斥鎖
ReentrantLock lock=new ReentrantLock();
@Override
public void run() {
for (int i = 0; i < 50; i++) {
//上鎖
lock.lock();
try {
if (count>0) {
System.out.println(Thread.currentThread().getName()+"吃了第"+count+"個蘋果");
count--;
}
} catch (Exception e) {
// TODO: handle exception
}finally {
//釋放鎖
lock.unlock();
}
}
}
public static void main(String[] args) {
// 初始化對象
AppleLock app=new AppleLock();
//啓動三個線程
new Thread(app, "A").start();
new Thread(app, "B").start();
new Thread(app, "C").start();
}
}
輸出結果:
package day25.thread;
//死鎖
public class DeadLockDemo implements Runnable{
//全局變量
boolean isFlag=false;
Object obj=new Object();
Object obj1=new Object();
//一個線程執行A
public void methodA() {
System.out.println("methodA=="+Thread.currentThread().getName());
synchronized (obj) {
System.out.println("obj已經加鎖");
synchronized (obj1) {
System.out.println("訪問obj1");
}
System.out.println("obj1訪問結束");
}
System.out.println("obj已經解鎖");
}
//一個線程執行B
public void methodB() {
System.out.println("methodB=="+Thread.currentThread().getName());
synchronized (obj1) {
System.out.println("----->obj1已經加鎖");
synchronized (obj) {
System.out.println("------>訪問obj");
}
System.out.println("------>obj訪問結束");
}
System.out.println("------>obj1解鎖");
}
@Override
public void run() {
if (!isFlag) {
isFlag=!isFlag;
methodA();
}else {
methodB();
}
}
public static void main(String[] args) {
// 創建對象
DeadLockDemo demo=new DeadLockDemo();
//啓動兩個線程
new Thread(demo, "A").start();
new Thread(demo, "B").start();
}
}
輸出結果:
package day25.timer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class Task extends TimerTask{
@Override
public void run() {
// 計時器要執行的任務
System.out.println("上九天攬月,下五洋捉鱉!");
}
}
public class TimerDemo {
public static void main(String[] args) throws ParseException {
// 創建一個計時器對象,可以設置爲守護線程+true
Timer timer=new Timer();
//添加執行的任務
//獲取當前時間戳
Calendar c=Calendar.getInstance();
Long times=c.getTimeInMillis();
//3s後執行
times+=3*1000;
//設置時間
c.setTimeInMillis(times);
//獲取日期
Date date=c.getTime();
//指定時間
SimpleDateFormat frm=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//將String類型的時間解析爲Date
date=frm.parse("2018-08-17 16:39:40");
Task ts=new Task();
timer.schedule(new Task(), date);//在指定的時間來執行指定的任務
timer.schedule(new TimerTask() {
@Override
public void run() {
// 執行任務
System.out.println("送你一顆小星星");
}
}, 5000);//以當前時間延遲多少毫秒執行一次任務
//指定首次出現時間
date=frm.parse("2018-08-17 16:45:00");
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("我不要!");
}
}, date, 10000);//在指定的時間執行任務,以一定的延時重複執行
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("那就分手吧!");
}
}, 2000, 5000);//以當前時間延遲多少s,再以固定的時間重複執行
//取消指定任務
//ts.cancel();
//取消timer內所有任務
//ts.cancel();
//清空已結束任務
//System.out.println(timer.purge());
}
}
輸出結果:
/**
* 單例設計模式
* 當前該類只能有一個對象,這個對象是共享的
* */
package day25.singleton;
//懶漢模式
public class SingletonDemo {
String name;
private static SingletonDemo singleton=null;
//構造方法私有化
private SingletonDemo(){
}
//通過類來獲取對象,設計一個靜態的方法
public static synchronized SingletonDemo getIntance() {
//創建對象,返回對象
if (singleton==null) {
singleton=new SingletonDemo();//初始化一個對象
}
return singleton;//將對象返回到方法調用處
}
}
package day25.singleton;
public class TestDemo {
public static void main(String[] args) {
/*SingletonDemo demo=SingletonDemo.getIntance();
demo.name="zz";
System.out.println(demo);
SingletonDemo demo1=SingletonDemo.getIntance();
System.out.println(demo1);
System.out.println(demo1.name);*/
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo.getIntance());
}
}).start();;
}
}
輸出結果:
package day25.singleton;
//餓漢模式
public class SingletonDemo1 {
private static final SingletonDemo1 singleton=new SingletonDemo1();
//構造方法私有化
private SingletonDemo1(){
}
//通過類來獲取對象,設計一個靜態的方法
public static synchronized SingletonDemo1 getIntance() {
return singleton;
}
}
package day25.singleton;
public class TestDemo1 {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonDemo1.getIntance());
}
}).start();
}
}
輸出結果:
package day25.test;
/**
* 生產者與消費者模型中,要保證以下幾點:
* 1 同一時間內只能有一個生產者生產 生產方法加鎖sychronized
* 2 同一時間內只能有一個消費者消費 消費方法加鎖sychronized
* 3 共享空間空時消費者不能繼續消費 消費前循環判斷是否爲空,空的話將該線程wait,釋放鎖允許其他同步方法執行
* 4 共享空間滿時生產者不能繼續生產 生產前循環判斷是否爲滿,滿的話將該線程wait,釋放鎖允許其他同步方法執行
*/
/**
* 生產者: 一直生產,直到生產完10個
* 在生產過程中,如果庫存中存滿(1個)則停止生產(由resource控制)
*/
//生產者
class Producer implements Runnable{
private ShareResource resource;//共享資源對象
public Producer(ShareResource resource) {
this.resource=resource;
}
@Override
public void run() {
System.out.println("生產中。。。");
for (int prodect = 1; prodect <=100; prodect++) {
try {
resource.setProdect(prodect);
} catch (InterruptedException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
}
}
/**
* 消費者:不斷消費,直到消費10個
* 消費過程中,如果庫存有包子則消費,沒包子等待(resource中wait())
*/
//消費者
class Consumer implements Runnable{
private ShareResource resource;//共享資源對象
public Consumer(ShareResource resource) {
this.resource=resource;
}
@Override
public void run() {
System.out.println("消費中。。。");
for (int i = 1; i <= 100; i++) {
try {
resource.getProdect();
} catch (InterruptedException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
}
}
/**
* 共享資源: 負責控制庫存,如果庫存沒包子了:通知生產者開始生產(notify), 並且通知消費者等待(wait)
* ,如果庫存有包子:通知生產者停止生產(wait), 並且通知消費者開始消費(notify)
* notify() / notifyall() :通知 實質上相當於 喚醒
* 加synchronized 爲了保證,同一時刻只有一個生產者在生產,只有一個消費者在消費
*/
//共享資源
class ShareResource{
private int prodect=-1;
public synchronized void setProdect(int prodect) throws InterruptedException {
waitIfFull();//如果滿,等待 被喚醒後繼續執行
this.prodect=prodect;
System.out.println("生產包子"+prodect+"個");
notify();
}
public synchronized int getProdect() throws InterruptedException {
waitIfEmpty();//如果空,等待 被喚醒後繼續執行
int p=this.prodect;
System.out.println("消費者購買了"+p+"個包子");
this.prodect=-1;
notify();
return p;
}
private synchronized void waitIfEmpty() throws InterruptedException {
if (prodect==-1) {
System.out.println("消費者等待!");
wait();
}
}
private synchronized void waitIfFull() throws InterruptedException {
if (prodect!=-1) {
System.out.println("生產者等待!");
wait();
}
}
}
public class ProducterComsumerDemo {
public static void main(String[] args) {
//初始化對象
ShareResource resource=new ShareResource();
//啓動線程
new Thread(new Producer(resource)).start();
new Thread(new Consumer(resource)).start();
}
}
輸出結果:
4.知識框架