欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java多线程 实例解析

程序员文章站 2024-03-31 16:31:58
java多线程实例 3种实现方法 java中的多线程有三种实现方式: 1.继承thread类,重写run方法。thread本质上也是一个实现了runnable的实例,他...

java多线程实例 3种实现方法

java中的多线程有三种实现方式:
1.继承thread类,重写run方法。thread本质上也是一个实现了runnable的实例,他代表一个线程的实例,并且启动线程的唯一方法就是通过thread类的start方法。
2.实现runnable接口,并实现该接口的run()方法.创建一个thread对象,用实现的runnable接口的对象作为参数实例化thread对象,调用此对象的start方法。
3.实现callable接口,重写call方法。callable接口与runnable接口的功能类似,但提供了比runnable更强大的功能。有以下三点
1).callable可以在人物结束后提供一个返回值,runnable没有提供这个功能。
2).callable中的call方法可以抛出异常,而runnable的run方法不能抛出异常。
3).运行callable可以拿到一个future对象,表示异步计算的结果,提供了检查计算是否完成的方法。

需要注意的是,无论用那种方式实现了多线程,调用start方法并不意味着立即执行多线程代码,而是使得线程变为可运行状态。

run start的区别

start方法是启动一个线程,而线程中的run方法来完成实际的操作。
如果开发人员直接调用run方法,那么就会将这个方法当作一个普通函数来调用,并没有多开辟线程,开发人员如果希望多线程异步执行,则需要调用start方法。

sleep wait的区别

1.两者处理的机制不同,sleep方法主要是,让线程暂停执行一段时间,时间一到自动恢复,并不会释放所占用的锁,当调用wait方法以后,他会释放所占用的对象锁,等待其他线程调用notify方法才会再次醒来。
2.sleep是threa的静态方法,是用来控制线程自身流程的,而wait是object的方法,用于进行线程通信。
3.两者使用的区域不同。sleep可以在任何地方使用,wait必须放在同步控制方法,或者语句块中执行。

synchronized notify wait的运用

synchronized关键字有两种用法,synchronized方法和synchronized语句块。
public synchronized void function(){}
synchronized(object){}
当某个资源被synchronized所修饰,线程1线程2等多个线程在共同请求这个资源,线程1先请求到,调用了对象的wait方法释放了对象的锁,此时线程2可以对这个对象进行访问,在工作结束时可以调用对象的notify方法,唤醒等待队列中正在等待的线程,此时被唤醒的线程将会再一次拿到对象锁,对对象进行操作。可以调用notifyall方法,唤醒等待队列中的所有线程。

需要注意的是一个线程被唤醒不代表立即获取对象锁,必须等调用的线程对象的方法推出synchronized块释放对象锁后,被唤醒的进程才会获得对象锁。

以下为大家提供一个简单的代码实例:

分别用runnable和thread方法实现,展示各个方法的

实现runnable实现多线程的方法

public class testrunnable implements runnable {

 private int time=1;
 private sourcea s;
 private string id = "001";
 public testrunnable(sourcea s){
  this.s = s;
 }
 public void settime(int time) {
  this.time = time;
 }
 
 @override
 public void run() {
  try {
   system.out.println("i will sleep"+ time);
   thread.sleep(time);
  } catch (interruptedexception e) {
   // todo auto-generated catch block
   e.printstacktrace();
  }

  synchronized(s){
   s.notify();
   system.out.println("我唤醒了002!");
   system.out.println("我存入了id"+id);
   s.setsource(id);
  }
 }

}

继承thread实现多线程的方法

public class testthread extends thread {
 private int time = 1;
 private sourcea s = null;
 string id = "002";
 
 public void settime(int time) {
  this.time = time;
 }
 
 public testthread(sourcea s){
  this.s = s ;
 }
 
 @override
 public void run() {
  try {
   system.out.println("i will sleep"+ time);
   sleep(time);
  } catch (interruptedexception e) {
   // todo auto-generated catch block
   e.printstacktrace();
  }
  
  synchronized(s){
   try {
    system.out.println("我"+ id +"要进行等待了");
    s.wait();
   } catch (interruptedexception e) {
    // todo auto-generated catch block
    e.printstacktrace();
   }
   system.out.println("我被唤醒了");
   system.out.println("我存入了id"+id);
   s.setsource(id);
  }
 }

}

sourcea类代码:

public class sourcea {
 private list<string> list = new arraylist<string>();
 public synchronized void getsource(){
  for(int i=0;i<list.size();i++){
   system.out.println(list.get(i));
  }
 }
 public synchronized void setsource(string id){
  list.add(id);
 }
}

test测试类代码:

public void test(){
  sourcea s = new sourcea();
  testthread tt = new testthread(s);
  testrunnable tr = new testrunnable(s);
  thread t = new thread(tr);
  system.out.println("调用线程1");
  tt.start();
  system.out.println("调用线程2");
  t.start();
 }

结果图片:

Java多线程 实例解析