java多線程方法

 

java多線程方法

進程是系統進行資源管理的基本單位;java

線程是進程中獨立的子任務安全

在使用多線程技術時,代碼的運行結果與代碼執行順序或調用順序是無關的多線程

java是單繼承不支持多繼承,因此有runnable接口dom

實例變量與線程安全

 

線程不共享數據:ide

public class MyThread extends Thread {測試

         private int count = 5;this

 

         public MyThread(String name) {spa

                   super();線程

                   this.setName(name);對象

         }

 

         public void run() {

                   super.run();

                   while (count > 0) {

                            count--;

                            System.out.println("--" + this.currentThread().getName() + "count" + count);

                   }

         }

}

public class Run {

         public static void main(String[] args) {

                   MyThread a = new MyThread("A");

                   MyThread b = new MyThread("B");

                   MyThread c = new MyThread("C");

                   a.start();

                   b.start();

                   c.start();

         }

}

 

線程間共享數據

 

public class MyThread extends Thread {

         private int count = 5;

 

         public MyThread(String name) {

                   super();

                   this.setName(name);

         }

 

         public void run() {

                   super.run();

                   while (count > 0) {

                            count--;

                            System.out.println("--" + this.currentThread().getName() + "count" + count);

                   }

         }

}

 

public class Run {

         public static void main(String[] args) {

                   MyThread mythread = new MyThread();

 

                   Thread a = new Thread(mythread, "A");

                   Thread b = new Thread(mythread, "B");

                   Thread c = new Thread(mythread, "C");

                   Thread d = new Thread(mythread, "D");

                   Thread e = new Thread(mythread, "E");

                   a.start();

                   b.start();

 

                   c.start();

                   d.start();

                   e.start();

         }

}

 

 

非線程安全:

public class LoginServlet {

         private static String usernameRef;

         private static String passwordRef;

 

         public static void doPost(String username,String password){

                   try {

                            usernameRef=username;

                            if(username.equals("a")){

                                     Thread.sleep(5000);

                            }

                            passwordRef=password;

                            System.out.println("username="+usernameRef+"password"+password);

                           

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

         }

 

}

public class ALogin extends Thread {

         @Override

         public void run() {

                   LoginServlet.doPost("a", "aa");

         }

}

public class BLogin extends Thread {

         @Override

         public void run() {

                   LoginServlet.doPost("b", "bb");

         }

}

 

public class Run {

         public static void main(String[] args) {

                   ALogin a = new ALogin();

                   a.start();

                   BLogin b = new BLogin();

                   b.start();

         }

}

 

 

線程安全 加synchronized,使線程排隊進入

 

 

 

留意i—與System.out.println()的異常

public class MyThread extends Thread {

         private int i = 5;

 

         public void run() {

                   System.out.println("i=" + (i--) + "threadName=" + Thread.currentThread().getName());

         }

}

 

public class Run {

         public static void main(String[] args) {

                   MyThread run = new MyThread();

                   Thread r1 = new Thread(run);

                   Thread r2 = new Thread(run);

                   Thread r3 = new Thread(run);

                   Thread r4 = new Thread(run);

                   Thread r5 = new Thread(run);

                   r1.start();

                   r2.start();

                   r3.start();

                   r4.start();

                   r5.start();

         }

}

println()在內部是同步的,可是i—的操做是在這個方法以前進行的,有發生非線程安全問題的機率

 

 

瞭解currentThread

public class CountOperate extends Thread {

         public CountOperate() {

                   System.out.println("CountOperate--begin");

                   System.out.println("Thread.currentThread().getname()=" + Thread.currentThread().getName());

                   System.out.println("this.getname()="+this.getName());

                   System.out.println("CountOperate--end");

                  

                  

                  

         }

         public void run(){

                   System.out.println("run--begin");

                   System.out.println("Thread.currentThread().getname()=" + Thread.currentThread().getName());

                   System.out.println("this.getname()="+this.getName());

                   System.out.println("run--end");

         }

}

 

 

public class Run {

         public static void main(String[] args) {

                   CountOperate c = new CountOperate();

                   Thread t1 = new Thread(c);

                   t1.setName("A");

                   t1.start();

         }

}

方法isAlive()測試程序是否處於活動狀態

public class CountOperate extends Thread {

         public CountOperate() {

                   System.out.println("CountOperate--begin");

                   System.out.println("Thread.currentThread().getname()=" + Thread.currentThread().getName());

                   System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive());

                   System.out.println("this.getname()="+this.getName());

                   System.out.println("this.isAlive()="+this.isAlive());

                   System.out.println("CountOperate--end");

                  

                  

                  

         }

         public void run(){

                   System.out.println("run--begin");

                   System.out.println("Thread.currentThread().getname()=" + Thread.currentThread().getName());

                   System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive());

                   System.out.println("this.getname()="+this.getName());

                   System.out.println("this.isAlive()="+this.isAlive());

                   System.out.println("run--end");

         }

}

 

public class Run {

public static void main(String[] args) {

         CountOperate c=new CountOperate();

         Thread t1=new Thread(c);

         System.out.println("main begin t1 s Alive="+t1.isAlive());

         t1.setName("A");

         t1.start();

         System.out.println("main end t1 isAlive="+t1.isAlive());

}

}

 

Sleep()方法是在指定的毫秒數內讓當前「正在執行的線程」休眠,這個「正在執行的線程」是指this.currentThread()返回的線程。

getId()是獲取線程的惟一標識

public class Test {

         public static void main(String[] args) {

                   Thread runThread = Thread.currentThread();

                   System.out.println(runThread.getName() + "---" + runThread.getId());

         }

}

 

中止線程

public class Run {

         public static void main(String[] args) throws InterruptedException {

                   MyThread thread = new MyThread();

                   thread.start();

                   Thread.sleep(2000);

                   thread.interrupt();

         }

}

 

調用interrupt方法並無中止線程,如何中止線程呢

 

判斷線程是否已經中斷

this.interrupted():測試當前線程是否已經中斷,當前線程是指運行this.interrupted()方法的線程;

public class Run2 {

         public static void main(String[] args) {

                   Thread.currentThread().interrupt();

                   System.out.println("是否中止1" + Thread.interrupted());

                   System.out.println("是否中止2" + Thread.interrupted());

                   System.out.println("end");

         }

}

 

結果:

是否中止1?true

是否中止2?false

end

爲何第二次中斷判斷的時候結果爲false呢,這是由於interrupted方法將中斷的狀態清除了,第二次拿不到中斷的狀態,因此返回false;

this.isINterrupted():測試線程Thread對象是否已經中斷狀態,但不清楚狀態標識

 

 

異常法-中止線程

 

public class MyThread extends Thread {

         @Override

         public void run() {

                   // TODO Auto-generated method stub

                   super.run();

                   for (int i = 0; i < 50000; i++) {

                            if (this.interrupted()) {

                                     System.out.println("已是中止狀態了,我要退出了");

                                     break;

 

                            }

                            System.out.println("i=" + (i + 1));

                   }

         }

}

 

 

public class MyThread extends Thread {

         @Override

         public void run() {

                   super.run();

                   try {

                            for (int i = 0; i < 500000; i++) {

                                     if (this.interrupted()) {

                                               System.out.println("已是中止狀態,我要退出了!");

                                               throw new InterruptedException();

                                     }

                                     System.out.println("i=" + (i + 1));

                            }

                            System.out.println("我在for下面");

                   } catch (Exception e) {

                            System.out.println("進入MyThread.java類run方法中的Catch了!");

                            e.printStackTrace();

                   }

                  

         }

}

 

在沉睡中中止

 

public class MyThread extends Thread {

         public void run() {

                   super.run();

                   try {

                            for (int i = 0; i < 1000; i++) {

                                     System.out.println("i =" + (i + 1));

                           

                            }

                            System.out.println("run begin");

                           

                            Thread.sleep(200000);

                   } catch (Exception e) {

                            System.out.println("sleep進入Catch!");

                   }

 

         }

}

 

暴力中止線程

 

public class MyThread extends Thread{

 

         private int i=0;

         @Override

         public void run() {

                   // TODO Auto-generated method stub

                   try {

                            while(true){

                                     i++;

                                     System.out.println("i="+i);

                                     Thread.sleep(1000);

                            }

                   } catch (InterruptedException e) {

                            e.printStackTrace();

                   }

         }

}

 

public class Run {

public static void main(String[] args) {

         try {

                   MyThread thread=new MyThread();

                   thread.start();

                   Thread.sleep(8000);

                   thread.stop();

         } catch (Exception e) {

                   e.printStackTrace();

         }

}

}

 

方法stop()和java.lang.ThreadDeath異常

public class MyThread extends Thread{

         @Override

         public void run() {

                  

                   try {

                            this.stop();

                   } catch (ThreadDeath e) {

                            System.out.println("catch fang fa ");

                            e.printStackTrace();

                   }

         }

}

 

public class Run {

         public static void main(String[] args) {

                   MyThread thread = new MyThread();

                   thread.start();

         }

}

 

若是強制讓線程中止則可能使一些清理工做得不到完成,另一種狀況就是對鎖定的對象進行了」解鎖」,致使數據得不到同步處理,獲得不一致的狀況。

 

 

釋放鎖的不良後果

使用stop()釋放鎖將會給數據形成不一致的結果

 

public class SynchronizedObject {

         private String username = "a";

         private String password = "aa";

 

         public String getUsername() {

                   return username;

         }

 

         public void setUsername(String username) {

                   this.username = username;

         }

 

         public String getPassword() {

                   return password;

         }

 

         public void setPassword(String password) {

                   this.password = password;

         }

 

         synchronized public void printString(String username, String password) {

                   try {

                            this.username = username;

                            Thread.sleep(100000);

                            this.password = password;

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

         }

 

}

 

 

public class MyThread extends Thread {

         private SynchronizedObject object;

 

         public MyThread(SynchronizedObject object) {

                   super();

                   this.object = object;

         }

 

         @Override

         public void run() {

                   object.printString("b", "bb");

         }

 

}

 

public class Run {

         public static void main(String[] args) {

                   try {

                            SynchronizedObject object = new SynchronizedObject();

                            MyThread thread = new MyThread(object);

                            thread.start();

                            Thread.sleep(200);

                            thread.stop();

                            System.out.println(object.getUsername() + ":" + object.getPassword());

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

         }

}

 

結果:

b:aa

強制stop形成數據不一致;

不建議使用stop()方法

 

 

使用return中止線程

使用interrupt()與return結合實現中止線程的效果

 

暫停線程

 

suspend與resume方法

public class MyThread extends Thread {

         private long i = 0;

 

         public long getI() {

                   return i;

         }

 

         public void setI(long i) {

                   this.i = i;

         }

 

         @Override

         public void run() {

                   try {

                            Thread.sleep(10);

                   } catch (InterruptedException e1) {

                            e1.printStackTrace();

                   }

                   try {

                            while (true) {

                                     i++;

                            }

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

         }

}

 

public class Run {

         public static void main(String[] args) {

                   try {

                            MyThread thread = new MyThread();

                            thread.start();

                            Thread.sleep(1000);

                            // A段

                            thread.suspend();

                            System.out.println("A=" + System.currentTimeMillis() + "i=" + thread.getI());

                            Thread.sleep(1000);

                            System.out.println("A=" + System.currentTimeMillis() + "i=" + thread.getI());

                            // B段

                            thread.resume();

                            Thread.sleep(1000);

                            // C段

                            thread.suspend();

                            System.out.println("B=" + System.currentTimeMillis() + "---i=" + thread.getI());

                            Thread.sleep(1000);

                            System.out.println("B=" + System.currentTimeMillis() + "---i=" + thread.getI());

 

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

         }

}

 

suspend與resume方法的缺點-獨佔

公共的同步對象的獨佔,其餘線程沒法訪問公共同步對象

public class Run {

         public static void main(String[] args) {

                   try {

                            final SynchronizedObject object = new SynchronizedObject();

                            Thread thread1 = new Thread() {

                                     public void run() {

                                               object.printString();

                                     }

                            };

                            thread1.setName("a");

                            thread1.start();

                            Thread.sleep(1000);

                            Thread thread2 = new Thread() {

                                     public void run() {

                                               System.out.println("thread2啓動了,但進不了printString()方法!只打印一個begin");

                                               System.out.println("由於printSring()方法被線程a鎖定而且永久suspend暫停了");

                                               object.printString();

                                     }

                            };

                            thread2.start();

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

         }

}

 

public class SynchronizedObject {

         synchronized public void printString() {

                   System.out.println("begin");

                   if (Thread.currentThread().getName().equals("a")) {

                            System.out.println("a線程永遠suspend 了!");

                            Thread.currentThread().suspend();

                   }

                   System.out.println("end");

         }

}

結果

begin

a線程永遠suspend 了!

thread2啓動了,但進不了printString()方法!只打印一個begin

由於printSring()方法被線程a鎖定而且永久suspend暫停了

 

suspend方法已經被做廢

suspend和resume方法缺點—不一樣步

public class MyObject {

         private String username = "1";

         private String password = "11";

 

         public void setValue(String u, String p) {

                   this.username = u;

                   if (Thread.currentThread().getName().equals("a")) {

                            System.out.println("暫停線程a");

                            Thread.currentThread().suspend();

                   }

                   this.password = p;

         }

 

         public void printUsernamePaasword() {

                   System.out.println(username + ":" + password);

         }

 

}

 

public class Run {

         public static void main(String[] args) throws InterruptedException {

                   final MyObject myobject = new MyObject();

                   Thread thread1 = new Thread() {

                            public void run() {

                                     myobject.setValue("a", "aa");

                                     ;

 

                            };

                   };

                   thread1.setName("a");

                   thread1.start();

                   Thread.sleep(500);

                   Thread thread2 = new Thread() {

                            public void run() {

                                     myobject.printUsernamePaasword();

                            };

                   };

                   thread2.start();

         }

}

結果:

暫停線程a

a:11

 

yield方法

         yield()方法的做用是放棄當前的Cpu資源,將它讓給其餘的任務去佔用Cpu執行時間,

但放棄的時間不肯定,有可能剛剛放棄,又立刻得到了Cpu時間片

public class MyThread extends Thread {

         @Override

         public void run() {

                   long beginTime = System.currentTimeMillis();

                   int count = 0;

                   for (int i = 0; i < 500000; i++) {

                            Thread.yield();

                            count = count + (i + 1);

                   }

                   long endTime = System.currentTimeMillis();

                   System.out.println("用時:" + (endTime - beginTime) + "毫秒!");

         }

}

 

public class Run {

         public static void main(String[] args) {

                   MyThread thread = new MyThread();

                   thread.start();

         }

}

當有Thread.yield()時,結果:用時:80毫秒!

當沒有Thread.yield()時,結果:用時:1毫秒!

線程的優先級

cpu優先執行優先級較高的線程對象中的任務

setPriority()

線程優先級的繼承特性

線程的優先級具備繼承性,併入A線程啓動B線程,則B線程的優先級與A是同樣的。public class MyThread1 extends Thread {

         @Override

         public void run() {

                   super.run();

                   System.out.println("MyThread1 run priority=" + this.getPriority());

                   MyThread2 thread2 = new MyThread2();

                   thread2.start();

         }

}

public class MyThread2 extends Thread {

         @Override

         public void run() {

                   System.out.println("MyThread2 run priority=" + this.getPriority());

         }

}

 

public class Run {

         public static void main(String[] args) {

                   System.out.println("main thread begin priority=" + Thread.currentThread().getPriority());

                   Thread.currentThread().setPriority(6);

                   System.out.println("main thread end priority=" + Thread.currentThread().getPriority());

                   MyThread1 thread1 = new MyThread1();

                   thread1.start();

 

         }

}

運行結果:main thread begin priority=5

main thread end priority=5

MyThread1 run priority=5

MyThread2 run priority=5

線程的優先級具備規則性,也就是CPU儘可能將執行的資源讓給優先級比較高的線程,誰先執行和代碼的調用順序無關

 

public class MyThread1 extends Thread {

         @Override

         public void run() {

                   long beginTime = System.currentTimeMillis();

                   long addResult = 0;

                   for (int j = 0; j < 10; j++) {

                            for (int i = 0; i < 5000; i++) {

                                     Random random = new Random();

                                     random.nextInt();

                                     addResult = addResult + i;

                            }

                   }

                   long endTime = System.currentTimeMillis();

                   System.out.println("★ ★ ★ ★ ★ thread 1 use time= " + (endTime - beginTime));

         }

}

public class MyThread2 extends Thread {

         @Override

         public void run() {

                   long beginTime = System.currentTimeMillis();

                   long addResult = 0;

                   for (int j = 0; j < 10; j++) {

                            for (int i = 0; i < 5000; i++) {

                                     Random random = new Random();

                                     random.nextInt();

                                     addResult = addResult + i;

                            }

                   }

                   long endTime = System.currentTimeMillis();

                   System.out.println("☆  ☆ ☆ ☆ ☆ thread 2 use time= " + (endTime - beginTime));

         }

}

public class Run {

         public static void main(String[] args) {

                   testB();

 

         }

 

         private static void testA() {

                   for(int i=0;i<5;i++){

                            MyThread1 thread1=new MyThread1();

                            thread1.setPriority(10);

                            thread1.start();

                            MyThread2 thread2=new MyThread2();

                            thread2.setPriority(1);

                            thread2.start();

                           

                   }

         }

        

        

         private static void testB() {

                   for(int i=0;i<5;i++){

                            MyThread1 thread1=new MyThread1();

                            thread1.setPriority(1);

                            thread1.start();

                            MyThread2 thread2=new MyThread2();

                            thread2.setPriority(10);

                            thread2.start();

                           

                   }

         }

 

}

 

 

優先級具備隨機性,優先級較高的線程不必定每一次都先執行完,與代碼的順序無關

 

 

守護線程

java線程中有兩種線程:用戶線程和守護線程

守護線程具備「陪伴」意思,當不存在非守護線程時,守護線程自動銷燬,典型的守護線程就是垃圾回收線程。

public class MyThread extends Thread {

 

         private int i = 0;

 

         @Override

         public void run() {

                   try {

                            while(true){

                                     i++;

                                     System.out.println("i="+(i));

                                     Thread.sleep(200);

                            }

                   } catch (Exception e) {

                            e.printStackTrace();

                   }

         }

}

public class Run {

         public static void main(String[] args) {

                   try {

                            MyThread thread = new MyThread();

                            thread.setDaemon(true);

                            thread.start();

                            Thread.sleep(1000);

                            System.out.println("wuThread out!");

 

                   } catch (Exception e) {

                            // TODO: handle exception

                   }

         }

}

result

i=1

i=2

i=3

i=4

i=5

wuThread out!

相關文章
相關標籤/搜索