Java多线程整理

A、Java中实现多线程的方式有两种:继承Thread类,实现Runnable接口。

class Thread1 extend Thread{

      public void run(){

       }

}

class Runnable1 implements Runnable{

    public void run(){

    }

}

其实Thread也是实现Runnable接口的

class Thread implements Runnable {
    //…
public void run() {
        if (target != null) {
             target.run();
        }
        }
}

两个孰优孰劣总结一下吧:

实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

 

B、线程强制执行

package com.tmt.test_code.thread;


class JoinThread implements Runnable {
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName());
        }
    }
 
    public static void main(String[] args) {
        JoinThread he = new JoinThread();
        Thread demo = new Thread(he,"线程");
        demo.start();
        for(int i=0;i<10;++i){
            if(i>5){
                try{
                    demo.join();  //强制执行demo
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println("main 线程执行-->"+i);
        }
    }
}

执行结果:

线程
main 线程执行-->0
main 线程执行-->1
main 线程执行-->2
main 线程执行-->3
main 线程执行-->4
main 线程执行-->5
线程
线程
main 线程执行-->6
main 线程执行-->7
main 线程执行-->8
main 线程执行-->9

说明在执行到大于5时,如果demo对应的线程还未执行完毕,则必须等它执行完毕后才能继续执行下面的程序。

 

C、sleep()和wait()的区别

package com.tmt.test_code.thread;

public class DeadLockThread implements Runnable{
 /**
 * 一个简单的死锁类及显示sleep()和wait()的区别
 * @author iStar
 * 当类的对象field_1=1时(T1),先锁定lock_1,睡眠1000毫秒,然后锁定lock_2;
 * 而T1在睡眠的时候另一个flag=2的对象(T2)线程启动,先锁定lock_2,睡眠1000毫秒,等待T1释放lock_1;
 * T1睡眠结束后需要锁定lock_2才能继续执行,而此时lock_2已被T2锁定;
 * T2睡眠结束后需要锁定lock_1才能继续执行,而此时lock_1已被T1锁定;
 * T1、T2相互等待,都需要对方锁定的资源才能继续执行,从而死锁。
 */
 int field_1 = 1;
 static Object lock_1 = new int[1];
 static Object lock_2 = new int[1];

 public void run(){
  if(field_1 == 1){
   synchronized (lock_1) {
    try {
//     lock_1.wait(1000);
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    synchronized (lock_2) {
     System.out.println("method1");
    }
   }
  }
  if(field_1 == 2){
   synchronized (lock_2) {
    try {
//     lock_2.wait(1000);
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    synchronized (lock_1) {
     System.out.println("method2");
    }
   }
  }
 }
 
 public static void main(String [] arg){
  DeadLockThread deadLockThread1 = new DeadLockThread();
  DeadLockThread deadLockThread2 = new DeadLockThread();
  deadLockThread1.field_1 = 1;
  deadLockThread2.field_1 = 2;
  Thread thread1 = new Thread(deadLockThread1);
  Thread thread2 = new Thread(deadLockThread2);
  thread1.start();
  thread2.start();
  
 }
}

当使用Thread.sleep(1000)时,打印不出任何东西。当注释掉Thread.sleep(1000),使用wait()时可以打印出method1 method2
说明:

1、在调用sleep()方法的过程中,线程不会释放对象锁。

2、在调用wait()方法的过程中,线程会释放对象锁,进入等待此对象的等待锁定池。只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

下面的例子也可以看出来

package com.tmt.test_code.thread;

/**
 * java中的sleep()和wait()的区别
 *
 * @author Hongten
 * @date 2013-12-10
 */
public class SleepWaitDeffirent {
 static Object object = new Object();

 public static void main(String[] args) {
  new Thread(new Thread1()).start();
  try {
   Thread.sleep(5000);
  } catch (Exception e) {
   e.printStackTrace();
  }
  new Thread(new Thread2()).start();
 }

 private static class Thread1 implements Runnable {
  @Override
  public void run() {
   synchronized (object) {
    System.out.println("enter thread1...");
    System.out.println("thread1 is waiting...");
    try {
     // 调用wait()方法,线程会放弃对象锁,进入等待此对象的等待锁定池
     object.wait();
    } catch (Exception e) {
     e.printStackTrace();
    }
    System.out.println("thread1 is going on ....");
    System.out.println("thread1 is over!!!");
   }
  }
 }

 private static class Thread2 implements Runnable {
  @Override
  public void run() {
   synchronized (object) {
    
    System.out.println("enter thread2....");
    System.out.println("thread2 is sleep....");
    // 只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
    object.notifyAll();
    // ==================
    // 区别
    // 如果我们把代码:TestD.class.notify();给注释掉,即TestD.class调用了wait()方法,但是没有调用notify()
    // 方法,则线程永远处于挂起状态。
    try {
     // sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,
     // 但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
     // 在调用sleep()方法的过程中,线程不会释放对象锁。
     Thread.sleep(100);
    } catch (Exception e) {
     e.printStackTrace();
    }
    System.out.println("thread2 is going on....");
    System.out.println("thread2 is over!!!");
    
   }
  
  }
 }
}

 

 


 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值