java thread study

      網(wǎng)友投稿 679 2025-04-02

      0. 用runnable創(chuàng)建線程具有面向?qū)ο蟮乃枷搿?/p>

      1. quartz ?定時(shí)器開(kāi)源庫(kù)。

      3. ?多線程間的互斥:

      (1)多線程間的互斥,用synchronized關(guān)鍵字,兩個(gè)線程用互斥鎖必須用同一個(gè)對(duì)象才能實(shí)現(xiàn)互斥。

      (2) 兩個(gè)非靜態(tài)函數(shù)前加synchronized關(guān)鍵字,它們的公用鎖是this,就是當(dāng)前對(duì)象實(shí)例。

      (3)靜態(tài)函數(shù)前加synchronized關(guān)鍵字,它用的鎖對(duì)象是.class字節(jié)碼,這個(gè)時(shí)u候與要將非靜態(tài)函數(shù)的synchronized(this)鎖改為synchronized(MyClass.class),即字節(jié)碼鎖

      兩個(gè)函數(shù)這才使用了同一個(gè)鎖:類(lèi)的字節(jié)碼對(duì)象,從而才實(shí)現(xiàn)了互斥。

      例如:2 個(gè)線程調(diào)用同一個(gè)Output對(duì)象的output1(“gaoxiaowei”)和output2(“l(fā)ichao”)兩個(gè)函數(shù), 會(huì)出現(xiàn)打印gaoxiaowei ?lichao ? ?gaolichao xiaowei這樣第二行錯(cuò)亂的問(wèn)題。

      在這里臨界資源是輸出屏幕? 我如果讓一個(gè)線程調(diào)用ouput1對(duì)象的output,然后另一個(gè)線程調(diào)用output2對(duì)象的output,在不加鎖的情況下會(huì)錯(cuò)亂嗎?

      答:

      (1)如果output函數(shù)的同步鎖是object.class字節(jié)碼時(shí),就不會(huì)錯(cuò)亂,因?yàn)閮蓚€(gè)線程 的兩個(gè)output對(duì)象在執(zhí)行output1函數(shù)時(shí),用的是同一把鎖object.class;

      (2)如果output的同步鎖是this,那么會(huì)錯(cuò)亂,因?yàn)閮蓚€(gè)線程分別持有2個(gè)對(duì)象output1與ouput2,是兩個(gè)this,因此output函數(shù)上的synchronized用的o是2把不同的

      this鎖,各自執(zhí)行各自的,都可以在這個(gè)臨界資源——屏幕上輸出。如第一個(gè)線程正在輸出gaolichao結(jié)果第二個(gè)線程打印lichao插到了第一個(gè)線程的輸出中間。

      (3)是的,這里的臨界資源就是顯示器,而不是公用的output類(lèi)對(duì)象,因?yàn)榧词?個(gè)線程分別創(chuàng)建一個(gè)output對(duì)象:output1與output2,如果鎖不是同一個(gè)的話,

      也會(huì)出現(xiàn)打印錯(cuò)誤。除非有2個(gè)顯示器,一個(gè)線程往顯示器1輸出,另一個(gè)線程往顯示器2輸出,這才不沖突,因?yàn)?個(gè)已經(jīng)是1對(duì)1,不存在公用競(jìng)爭(zhēng)問(wèn)題。

      4.多線程間的同步

      wait 和 notify

      現(xiàn)在有這么一個(gè)題目:子線程執(zhí)行10次,然后主線程再執(zhí)行100次,接著輪到子線程再執(zhí)行10次,然后主線程又執(zhí)行100次,兩個(gè)線程這樣輪流執(zhí)行,總共50回。

      step1: 定義一個(gè)業(yè)務(wù)類(lèi),封裝兩個(gè)函數(shù):(1)打印10次sub ?(2)打印100次main;

      step2: 定義1個(gè)子線程,外層for循環(huán)都是50次,然后每循環(huán)1次調(diào)用業(yè)務(wù)類(lèi)中的 函數(shù)(1u)打印10次sub

      主線程,外層for循環(huán)都是50次,然后每循環(huán)1次調(diào)用業(yè)務(wù)類(lèi)中的 函數(shù)(2)打印50次main

      step3:先解決互斥問(wèn)題:就是在打印sub的10次循環(huán)時(shí),不能穿插打印main;同理打印main的100次的時(shí)候,不能穿插子線程的sub打印。這個(gè)好辦,給業(yè)務(wù)類(lèi)的

      函數(shù)1和函數(shù)2前加synchronized關(guān)鍵字,這樣就實(shí)現(xiàn)了打印sub的10次時(shí),由于正在占用同一個(gè)對(duì)象鎖this,因此它不會(huì)被函數(shù)(2)打斷。

      step4:解決同步配合問(wèn)題,先子線程打印10次,子線程打印完了,然后執(zhí)行notify,喚醒主線程去打印100次(主線程剛開(kāi)始會(huì)調(diào)用waite),然后主線程打印完100次,再去喚醒子線程去打印。

      注意synchronized括起來(lái)的對(duì)象要與調(diào)用wait,notify是同一個(gè)對(duì)象,并且這個(gè)object.notify,object.wait中的object要被括在synchronized里,否則會(huì)報(bào)錯(cuò):Java.lang.IllegalMonitorStateException

      實(shí)例代碼如下:

      import Java.util.concurrent.atomic.AtomicInteger;

      public class TraditionalThreadCommunication {

      /**

      * @param args

      */

      public static void main(String[] args) {

      final Business business = new Business();

      new Thread(

      new Runnable() {

      @Override

      public void run() {

      for(int i=1;i<=50;i++){

      business.sub(i);

      }

      }

      }

      ).start();

      for(int i=1;i<=50;i++){

      business.main(i);

      }

      }

      }

      class Business {

      private boolean bShouldSub = true;

      Object obj;

      public Business()

      {

      obj = new Object();

      }

      public synchronized void sub(int i){

      synchronized(obj)

      {

      while(!bShouldSub){

      try {

      obj.wait();

      } catch (InterruptedException e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

      }

      }

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

      System.out.println("sub thread sequence of " + j + ",loop of " + i);

      }

      bShouldSub = false;

      obj.notify();

      }

      }

      public ?void main(int i){

      synchronized(obj)

      {

      while(bShouldSub){

      try {

      obj.wait();

      } catch (InterruptedException e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

      }

      }

      for(int j=1;j<=100;j++){

      System.out.println("main thread sequence of " + j + ",loop of " + i);

      }

      bShouldSub = true;

      obj.notify();

      }

      }

      }

      或者:

      public class TraditionalThreadCommunication {

      public static void main(String[] args) {

      final Business business = new Business();

      new Thread(

      new Runnable() {

      @Override

      public void run() {

      for(int i=1;i<=50;i++){

      business.sub(i);

      }

      }

      }

      ).start();

      for(int i=1;i<=50;i++){

      business.main(i);

      }

      }

      }

      class Business {

      private boolean bShouldSub = true;

      public synchronized void sub(int i){

      while(!bShouldSub){

      try {

      this.wait();

      } catch (InterruptedException e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

      }

      }

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

      System.out.println("sub thread sequence of " + j + ",loop of " + i);

      }

      bShouldSub = false;

      this.notify();

      }

      public synchronized void main(int i){

      while(bShouldSub){

      try {

      this.wait();

      } catch (InterruptedException e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

      }

      }

      for(int j=1;j<=100;j++){

      System.out.println("main thread sequence of " + j + ",loop of " + i);

      }

      bShouldSub = true;

      this.notify();

      }

      }

      5. 多線程間的互斥,用synchronized關(guān)鍵字包裹的函數(shù)內(nèi)部如果生成了 一個(gè)死循環(huán)線程,那么這個(gè)函數(shù)的鎖子能釋放嗎?

      答:能。因?yàn)閟ynchronized是用于當(dāng)前線程同步的;還有就是生成的那個(gè)線程并不會(huì)阻塞當(dāng)前函數(shù)的執(zhí)行,函數(shù)執(zhí)行完成后自然會(huì)釋放synchronized鎖。

      6.當(dāng)一個(gè)線程處于sleep時(shí),Thread.isAlive函數(shù)返回false

      7.線程范圍內(nèi)的共享變量

      同一個(gè)變量,在線程間共享,例如下面的變量x,線程內(nèi)獨(dú)立,表示線程內(nèi)是一份獨(dú)立的數(shù)據(jù)。

      (1)可以用hashmap.put(Thread.name, data);? 來(lái)實(shí)現(xiàn)

      (2)ThreadLocal來(lái)實(shí)現(xiàn)

      下面的x,是演示單個(gè)共享變量

      package cn.itcast.heima2;

      import java.util.HashMap;

      import java.util.Map;

      import java.util.Random;

      public class ThreadLocalTest {

      private static ThreadLocal x = new ThreadLocal();

      private static ThreadLocal myThreadScopeData = new ThreadLocal();

      public static void main(String[] args) {

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

      new Thread(new Runnable(){

      @Override

      public void run() {

      int data = new Random().nextInt();

      System.out.println(Thread.currentThread().getName()

      + " has put data :" + data);

      x.set(data);

      /*?? ??? ??? ??? ??? ?MyThreadScopeData myData = new MyThreadScopeData();

      myData.setName("name" + data);

      myData.setAge(data);

      myThreadScopeData.set(myData);*/

      MyThreadScopeData.getThreadInstance().setName("name" + data);

      MyThreadScopeData.getThreadInstance().setAge(data);

      new A().get();

      new B().get();

      }

      }).start();

      }

      }

      static class A{

      public void get(){

      int data = x.get();

      System.out.println("A from " + Thread.currentThread().getName()

      + " get data :" + data);

      /*?? ??? ??? ?MyThreadScopeData myData = myThreadScopeData.get();;

      java thread study

      System.out.println("A from " + Thread.currentThread().getName()

      + " getMyData: " + myData.getName() + "," +

      myData.getAge());*/

      MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();

      System.out.println("A from " + Thread.currentThread().getName()

      + " getMyData: " + myData.getName() + "," +

      myData.getAge());

      }

      }

      static class B{

      public void get(){

      int data = x.get();

      System.out.println("B from " + Thread.currentThread().getName()

      + " get data :" + data);

      MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();

      System.out.println("B from " + Thread.currentThread().getName()

      + " getMyData: " + myData.getName() + "," +

      myData.getAge());

      }

      }

      }

      class MyThreadScopeData{

      private MyThreadScopeData(){}

      public static /*synchronized*/ MyThreadScopeData getThreadInstance(){

      MyThreadScopeData instance = map.get();

      if(instance == null){

      instance = new MyThreadScopeData();

      map.set(instance);

      }

      return instance;

      }

      //private static MyThreadScopeData instance = null;//new MyThreadScopeData();

      private static ThreadLocal map = new ThreadLocal();

      private String name;

      private int age;

      public String getName() {

      return name;

      }

      public void setName(String name) {

      this.name = name;

      }

      public int getAge() {

      return age;

      }

      public void setAge(int age) {

      this.age = age;

      }

      }

      8.多個(gè)線程間共享數(shù)據(jù)的探討

      方法1:new Thread(new Runnable()

      {

      data1.decrement();

      }

      )

      方法2:?? ??? ?new Thread(new MyRunnable1(data2)).start();

      new Thread(new MyRunnable2(data2)).start();

      將數(shù)據(jù)data2作為構(gòu)造函數(shù)參數(shù)傳到Runnable里去。

      方法3:

      定義2個(gè)Runnable內(nèi)部類(lèi),訪問(wèn)外部類(lèi)的成員變量j

      方法1和方法2的代碼:

      package cn.itcast.heima2;

      public class MultiThreadShareData {

      private static ShareData1 data1 = new ShareData1();

      public static void main(String[] args) {

      ShareData1 data2 = new ShareData1();

      new Thread(new MyRunnable1(data2)).start();

      new Thread(new MyRunnable2(data2)).start();

      final ShareData1 data1 = new ShareData1();

      new Thread(new Runnable(){

      @Override

      public void run() {

      data1.decrement();

      }

      }).start();

      new Thread(new Runnable(){

      @Override

      public void run() {

      data1.increment();

      }

      }).start();

      }

      }

      class MyRunnable1 implements Runnable{

      private ShareData1 data1;

      public MyRunnable1(ShareData1 data1){

      this.data1 = data1;

      }

      public void run() {

      data1.decrement();

      }

      }

      class MyRunnable2 implements Runnable{

      private ShareData1 data1;

      public MyRunnable2(ShareData1 data1){

      this.data1 = data1;

      }

      public void run() {

      data1.increment();

      }

      }

      class ShareData1 /*implements Runnable*/{

      /*?? ??? ?private int count = 100;

      @Override

      public void run() {

      // TODO Auto-generated method stub

      while(true){

      count--;

      }

      }*/

      private int j = 0;

      public synchronized void increment(){

      j++;

      }

      public synchronized void decrement(){

      j--;

      }

      }

      方法3的代碼:

      外部類(lèi):

      private int j = 0;

      public synchronized void increment(){

      j++;

      }

      public synchronized void decrement(){

      j--;

      }

      內(nèi)部類(lèi):

      MyIncrementRunnable()

      {

      increment();? //內(nèi)部類(lèi)調(diào)用外部類(lèi)成員,還是以外部類(lèi)對(duì)象為同步鎖

      }

      MyDecrementRunnable()

      {

      decrement();

      }

      Java 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:生產(chǎn)管理業(yè)務(wù)流程:優(yōu)化生產(chǎn)效率的關(guān)鍵
      下一篇:excelst2003行列轉(zhuǎn)置的教程
      相關(guān)文章
      亚洲国产日韩在线人成下载| 国产精品亚洲综合专区片高清久久久 | 亚洲欧洲国产综合AV无码久久| 亚洲AV永久无码精品水牛影视| 亚洲综合无码精品一区二区三区 | 亚洲精品美女久久久久99小说| 国产亚洲视频在线观看网址| 日韩色视频一区二区三区亚洲| 精品国产日韩亚洲一区91| 亚洲欧洲日产国码久在线| 亚洲AV无码国产一区二区三区 | 豆国产96在线|亚洲| 精品久久亚洲一级α| 亚洲AⅤ优女AV综合久久久| 夜色阁亚洲一区二区三区| 亚洲第一区在线观看| 亚洲无线一二三四区手机| 亚洲午夜爱爱香蕉片| 久久久久亚洲精品天堂久久久久久 | 亚洲精品白色在线发布| 亚洲麻豆精品果冻传媒| 亚洲国产情侣一区二区三区| 亚洲综合色一区二区三区小说| 久久亚洲美女精品国产精品 | 国产精品无码亚洲精品2021 | 亚洲国产精品成人AV在线| 亚洲熟妇自偷自拍另欧美| 亚洲av日韩综合一区久热| 亚洲国产成人久久精品99 | 中文字幕 亚洲 有码 在线| 亚洲v高清理论电影| 亚洲精品欧洲精品| wwwxxx亚洲| 久久久久久亚洲精品无码| 亚洲精品第一国产综合精品99 | 亚洲中文字幕无码不卡电影| 亚洲精品无码久久一线| 亚洲一本综合久久| 国产亚洲玖玖玖在线观看| 日韩亚洲人成网站| 中文字幕不卡亚洲|