/*
* 進程:
* 定義:運行中的程序稱為進程,進程負責內存空間的分配;
*
* 說明:單核cpu在一致時間翩只能運行一個程序。所有運行的程序實際上是在爭奪CPU的使用權,cpu在短時間內快速切換來執行不同的程序;
* 這就是多任務運行實現機制;
*
* 線程:
*? 定義:線程負責代碼的執行
*? 運行任何一個java程序的時候,jvm都會創建一個main線程,并執行main中的代碼
* 一個java應用程序至少有2個線程,一個是main線程,負責執行代碼,一個是垃圾回收器線程負責回收垃圾
*
*多線程的好處:
* 1. 一個進程同時執行多個任務;
* 2. 提高了資源的利用率;
*
*多線程的弊端
* 1. 增加了cpu的負擔;
* 2. 降低了一個進程中線程的執行概率:
* 2. 出現了死鎖的問題;
*
*創建多線程
* 方式一:
* 1. 定義一個子類去繼承Thread類;
* 2. 重寫Thread的run方法:
* 說明:jvm創建的主線程所運行的代碼就是main方法中的代碼,而自定義的線程所要執行的代碼是放在run方法中的,重寫的目的是把自定義線程所要運行的代碼放入到run方法中.
* 3. 創建THread的子類對象,調用Start()方法開啟線程;
* 說明:一旦開啟了線程,jvm就會自動執行run方法中的代碼,而不能手動調用run方法,否則就會像調用普通方法一樣而不會開啟新進場;
* 方式二:
** 線程創建方式二:
* 1, 自定義一個類實現Runnable接口;
* 2. 實現Runnable的run方法, 把自定義線程代碼放在run方法中;
* 3. 創建Runnable實現類的對象;
* 4. 創建Thread類的對象;將Runnable實現類的對象傳遞給Thread類的構造函數;
*? 5. 調用Thread類對象的start方法;
*
* 注意的問題:
* 1. Runnable的實現類對象并不是線程對象,而是Runnable的實現類而已。只有Thread和Thread的子類對象才是線程duix
* 2. 將Runnable的實現類對象作為參賽傳遞給Thread的作用是將其run方法中代碼傳遞給Thread對象,底層是Thread中
* 的run方法調用了傳遞過來的Runnable實現類對象中的run方法.
*線程的生命周期
/*
* 線程類常用方法
* Thread(String anem) 初始化線程的方法
*
* getName() 返回線程的方法
* sleep() 指定線程的睡眠時間,毫秒為單位,sleep是靜態方法,那個靜態方法執行了該方法,那么就是那個線程睡眠;
* getPriority() 返回當前線程的優先級, 默認線程的優先級是5
* setPriority(int newPriority) 設置線程的優先級,雖然設置了線程的優先級,但是具體取決于底層的操作系統的實現(最大的優先級是10,最小的是1,默認為5);
* currentThread() 返回cpu正在執行的線程數;靜態方法,那么線程執行了該方法就返回當前線程對象
*線程安全問題:
* 1. 出現原因: 有多個線程共享數據
* 2. 有多個語句操作共享數據;
* 線程同步機制:
* 方式一: 同步代碼塊
* 使用格式:
* synchronized(鎖對象)
* { 同步代碼;...}
* 注意:
* 1. 鎖對象可以是任意的對象,只要是對象都可以;
* 原理是任何對象內部都隱式維護了一個狀態變量(非靜態成員變量),而同步機制就利用這了這個狀態來實現鎖機制;
* 2. 在同步代碼塊中調用了sleep()方法,那么在線程休眠的時候不會釋放鎖;
* 3. 只有真正出現線程安全問題,才使用同步代碼塊來解決;
* 4. 同步代碼塊中使用的鎖必須是唯一的,不能使用匿名對象;因此要使用靜態對象;
* 最簡單的方式是使用一個字符串常量,因為字符串存在于字符串常量池中,是共享的.
*
* 方式二:同步函數
* 使用synchronized修飾一個函數
* 格式:
* synchronized 函數名(){}
* 注意:
* 1. 如果synchronized修飾非靜態成員函數,那么線程鎖是this對象,如果是靜態成員函數,那么線程鎖是函數所在類的字節碼文件;
* 2. 同步函數的鎖對象是固定的,不能修飾;
*
* 說明:推薦使用同步代碼塊
* 1. 同步代碼塊的鎖對象可以隨意指定,方便控制,同步函數的鎖是固定的,不能指定:
* 2. 同步代碼塊可以方便需要同步代碼的范圍,同步函數必須是函數中的整個代碼:
*/
public class Demo17 extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for(int i=0; i<10000; i++)
{
System.out.println("我是自定義線程" + i);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//創建自定義線程對象
Demo17 d17 = new Demo17();
d17.start();
for(int i=0; i<10000; i++)
{
System.out.println("我是主線程" + i);
}
}
}
線程創建方式二:
public class Demo5 implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<100; i++)
{
System.out.println(Thread.currentThread().getName()+"自定義線程"+i);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Demo5 d3 = new Demo5();
Thread td = new Thread(d3, "張三兒");
td.start();
for(int i=0; i<100; i++)
{
System.out.println("Main方法的線程"+i );
}
}
}