zoukankan      html  css  js  c++  java
  • Java多线程基础学习(一)

    1. 创建线程   

    1.1 通过构造函数:public Thread(Runnable target, String name){}  或:public Thread(Runnable target){}
    示例:
    Thread thread1 = new Thread(new MyThread(), "mythread");
    class MyThread extends Thread(){
            public void run(){
                 System.out.println("My First Thread');
            }
    }
    1.2 直接实现Runnable接口:
    示例:
    Thread thread2 = new Thread(new Runnable{}{
             public void run(){
                      System.out.println("This is my thread.");        
              }
    });
     
    2. 运行线程   
    thead1.start()    
     
    3. sleep
    try{
        #休眠1000ms
        Thread.sleep(1000);
    }catch(InterruptedException e){
        e.printStackTrace();
    }
     
    4. getName() 获取线程名字, getId()获取线程id
    System.out.println(Thread.currentThread().getName() + ":"+ Thread.currentThread().getId);
     
    5. 停止线程,
    千万不用stop(),stop会立即终止线程。
    通过interrupt()中断线程,但是中断并没有停止线程,配合异常来实现:
    public class Main {
       public static void main(String[] args) throws InterruptedException {
          try{
              Thread thread1=new Thread(new TheThread(),"thread1");
              thread1.start();
              Thread.sleep(2000);
              thread1.interrupt();
          }catch (InterruptedException e){
                      e.printStackTrace();
           }
       }
    }
       class TheThread extends Thread{
         public void run() {
            super.run();
            for (int i = 0; i < 10; i++) {
               if(this.interrupted()){
                  break;
            }
            System.out.println(Thread.currentThread().getName() + ":" + i);
         }
       }
    }

     注意,如果在TheThread类里加入catch InterruptException的话,可能会导致interrupt被捕获,而绕过if(this.interrupted())的判断而无法终止线程。

    6. 等待和通知        
    线程等待:当前线程就处于等待状态,直到其他线程调用了notify()方法,线程才会继续执行
    public final void wait() throws InterruptedException
    线程通知:
    public final native void notify()

     注意:在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出同步代码块中。

     1 package wait.notify;
     2 
     3 public class ThreadWaitNotifyTest {
     4     final static Object object=new Object();
     5     public static class T1 extends Thread{
     6         public void run(){
     7             System.out.println(System.currentTimeMillis()+": T1 start");
     8             synchronized (object){
     9                 try {
    10                     System.out.println(System.currentTimeMillis()+": T1 wait");
    11                     object.wait();
    12                 } catch (InterruptedException e) {
    13                     e.printStackTrace();
    14                 }
    15             }
    16             System.out.println(System.currentTimeMillis()+": T1 end");
    17         }
    18     }
    19     public static class T2 extends Thread{
    20         public void run(){
    21             System.out.println(System.currentTimeMillis()+": T2 start");
    22             synchronized (object){
    23                 System.out.println("T2 synchonized code start.");
    24                 object.notify();
    25                 try {
    26                     Thread.sleep(2000);
    27                 } catch (InterruptedException e) {
    28                     e.printStackTrace();
    29                 }finally{
    30                     System.out.println("T2 synchonized code end.");
    31                 }
    32                 
    33             }
    34             try {
    35                 Thread.sleep(2000);
    36             } catch (InterruptedException e) {
    37                 e.printStackTrace();
    38             }
    39             System.out.println(System.currentTimeMillis()+": T2 end");
    40         }
    41     }
    42     public static void main(String[] args){
    43         Thread thread1=new T1();
    44         Thread thread2=new T2();
    45         thread1.start();
    46         thread2.start();
    47     }
    48 }

    输出结果:

    7. 线程优先级
    高优先级的线程将会获得更多的CPU资源。一共分为10个优先级。
    public final void setPriority(int newPriority)
     
    源码分析:
    public final void setPriority(int newPriority) {
            ThreadGroup g;
            checkAccess();
            if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
                throw new IllegalArgumentException();
            }
            if((g = getThreadGroup()) != null) {
                if (newPriority > g.getMaxPriority()) {
                    newPriority = g.getMaxPriority();
                }
                setPriority0(priority = newPriority);
            }
    }
    public final static int MIN_PRIORITY = 1;
    public final static int NORM_PRIORITY = 5;
    public final static int MAX_PRIORITY = 10;
    可见线程最高优先级为10, 最低为1, 默认为5.
    当设定的newPriority高于该线程组ThreadGroup的最高Priority时,只能分配该线程组的最高Priority
     
    8. 守护线程
    类似守护进程,Java存在两种线程:用户线程和守护线程。它是一种特殊线程,执行的是一种后台服务,当一个系统中不存在非守护线程的时候,守护线程会自己销毁。典型的守护线程:JVM的垃圾回收线程。
    public final void setDaemon(boolean on)
     
    示例:
    public class Main {
        public static void main(String[] args) throws InterruptedException {
           TheThread theThread=new TheThread();
            theThread.setDaemon(true);//设置守护线程
            theThread.start();
            Thread.sleep(5000);
            System.out.println("全都退出啦");
        }
        public static class TheThread extends Thread{
            public void run(){
                int i = 0;
                while (true){
                    i++;
                    System.out.println(Thread.currentThread().getId()+":"+i);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    源码分析:
    设置线程为用户线程(user thread)或守护线程(daemon thread),当剩余运行的线程均为守护线程时,JVM会退出。
     public final void setDaemon(boolean on) { 
            checkAccess(); 
            if (isAlive()) { 
                throw new IllegalThreadStateException(); 
            } 
            daemon = on; 
        }
    其中checkAccesss()方法如下:
     public final void checkAccess() {
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkAccess(this);
            }
        }
    该方法用于判断当前运行的线程是否有修改此线程的权限。
    而public final native boolean isAlive();用于判断该线程是否处于alive状态,即该线程是否已经start,且没有die。
    当isAlive的话就会抛出IllegalThreadStateException异常。
    所以,设置守护线程的方法,逻辑就是先判断当前线程是否有修改的权限,再判断是否处于alive状态,如果不处于alive状态,则根据boolean变量on的值更改它的状态,即true:设为daemon线程,false:设为user线程。
     
     
     
     
     
     
     
     
     
    zni.feng@gmail.com
  • 相关阅读:
    idea原项目debug模式正常启动,突然长时间卡住无法启动的解决办法
    IntelliJ IDEA下SVN的配置及使用说明
    IntelliJ IDEA打开带SVN信息的项目不显示SVN信息——解决方法
    头文件string.h,cstring与string
    跨进程边界共享内核对象
    Windows进程间通讯(IPC)----共享内存
    Windows进程间通讯(IPC)----内存映射文件
    Windows进程间通讯(IPC)----管道
    C异常处理和C++异常处理的对比
    NtQuerySystemInformation获取进程/线程状态
  • 原文地址:https://www.cnblogs.com/znicy/p/5647706.html
Copyright © 2011-2022 走看看