java中多线程的同步异步操作

程序在计算机运行为了提高效率便不能使用单一线程,所以多线程的出现解决了这个单线程效率低的问题,

在了解线程中,要先分清进程和线程。

1:一个程序有可以是有多个进程来运行的,每个进程有自己独立的内存空间去运行操作数据。

2:线程是处于进程中的更小执行单位,每个进程中有多个线程,每个线程有独立的内存空间去操作对象中的变量,又共同享有,同一块内存空间存放共同处理的对象。

由大到小的顺序是:程序>进程>线程

正常默认创建的线程是异步线程,线程还有一种是同步线程

异步线程:多个线程可以同时对一个对象进行操作。

同步线程:线程不能同时对一个对象进行操作。

有三种能创建线程的方式:(以下3种例子的线程都为异步线程)

   方法1:将所需要的类去继承Thread类,Thread类是在java的lang包中。继承Thread,重写run的方法,在主类main中去创建线程对象,并调用Thread中的start 方法。  代码如下:

public  class  Demo{
    public static void main(String [] args){
          //创建一个ThreadTest 线程 t1
         ThreadTest  t1 = new ThreadTest(10,"线程A");
          // t调用方法start() 通知cpu调用run方法执行
          t1.start();
          //创建一个ThreadTest 线程 t2
          ThreadTest  t2 = new ThreadTest(10,"线程B");
          t2.start();
    }


    //继承Thread 的ThreadTest类
   static class ThreadTest extends Thread{
	   //定义一个变量num,线程名字name;
	   	  int num;
	   	  String name;
	   //重写构造方法传入参数num,name
	   	public ThreadTest(int num,String name) {
			super();
			this.num = num;
			this.name = name;
		}

	   	  
	   	  
          //重写run方法
          public void run(){
        	  //重写的方法run中调用Test方法
        	  Test();
          }
          public void Test(){
        	  for(int i = 0;i<20;i++){
        		  System.out.println(name+"<>"+num++);
        	  }
          }
	

    }
}  

 方法2:实现接口runnable也可以创建线程,runnable中不能直接用Thread的方法,所以需要创建一个Thread对象来包装由实现runnable接口的线程创建的对象,再用包装好的Thread对象来调用Thread中的 start方法。  代码如下:

public class Demo1 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//创建RunnableTest类的第一个线程t1
		RunnableTest r1 = new RunnableTest(10,"线程A");
		//用Thread包装r1对象 
		Thread t1 = new Thread(r1);
		t1.start();
		
		//创建RunnableTest类的第二个线程t2
				RunnableTest r2 = new RunnableTest(10,"线程B");
				//用Thread包装r1对象 
				Thread t2 = new Thread(r2);
				t2.start();
	}
	
	
	
	static class RunnableTest implements Runnable{
		int num;
		String name;
		//重载构造函数
		public RunnableTest(int num,String name){
			this.name = name;
			this.num = num;
		}
		@Override
		//重写run方法
		public void run() {
			//调用 Test()方法
			Test();
		}
		public void Test(){
			for(int i = 0;i<20;i++){
				System.out.println(name+"执行了  "+num++);
			}
		}
		
	}
}

 方法3:在java的util包中有timer和timertast类,实现timertast类,也可以创建线程,timertast是定时器类

代码如下:

import java.util.Timer;
import java.util.TimerTask;

public class Demo2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//创建一个Timertest对象
		Timertest t = new Timertest(10,"线程A");
		//用Timer创建定时器对象t1
		Timer T = new Timer();
		//用定时器对象调用方法,
		T.schedule(t, 100);
		
		//创建一个Timertest对象
		Timertest t1 = new Timertest(10,"线程B");
		//用Timer创建定时器对象T1
		Timer T1 = new Timer();
		//用定时器对象调用方法,
		T1.schedule(t1, 100);
		
	}
	static class Timertest extends TimerTask{
		int num;
		String name;
		
		public Timertest(int num,String name){
			this.name = name;
			this.num = num;
		}

		@Override
		//重写run方法
		public void run() {
			Test();
		}
		public void Test(){
			
			for(int i = 0;i<20;i++){
				System.out.println(name+"执行了  "+num++);
			}
		}
		
	}
}

上面3种方法都可以创建线程,(例子中的一些方法未注释,自己查API文档,在什么包中都有注明)。

在异步线程中,继承Thread后中有许多方法时比较常用的。

例如:Thread.currentThread()  获得当前线程对象

     Thread.sleep(毫秒)       当前线程休眠指定的毫秒数

     setPriority(1~10); 设置线程的优先级  (1~10,数字越大,优先级越高,默认为5)

     getPriority();           获得线程的优先级

     join()    等待该线程执行完毕(也称合并线程,单线程,指等一个线程执行结束后,再执行                                            另一个线程)

     yield()    暂停当前正在执行的线程对象,并执行其他线程(当前线程让出执行的时间片段,由下一个线程使用。也有可能下个线程还是自己,所以不是绝对)。

     getState()            获得线程的状态

     isAlive()            是不是活动的线程(不常用)

     start()    启动线程的方法(常用)(只是给虚拟机一个信号,当前这个线程可以执行run方法了 线程的run                                                             方法什么时候开始执行,是由CPU调度的)

线程中存在五种状态:

     新建状态:处于创建状态,未调用start()方法。

     runnable:就绪状态,调用start()方法,等待CPU调度。

     running  :cpu调度后,处于运行状态。

     not running:处于阻塞状态下,暂停状态(可能由于方法join()或者yield()而导致的状态)。

     dead:线程执行结束时的死亡状态。

在同步线程中不可以对同一个对象进行操作,所以当一个线程在操作时,另一个线程必须等到前一个线程执行结束才可以接着执行,有4种方法可以实现线程的同步。

方法一:synchronized

        方式一:使用synchronized(对象) 锁住需要同步的代码块

        方法二:使用synchronized锁住需要同步的方法

        方法三:从jdk1.5开始提供的对象锁

                   Lock l = new ReentrantLock();

                   //上锁

                   l.lock();

                    //解锁

                   l.unlock();

        方法四:使用wait-notify机制

线程在现在的B/S主流情况下时非常实用的,一个网页是要同时支持多人浏览的,所以在多线程情况下,一(网页)对多(用户)的情况就可以解决。

             

猜你喜欢

转载自771235695.iteye.com/blog/2370756