zoukankan      html  css  js  c++  java
  • android基础篇------------java基础(12)(多线程操作)

    《一》基本概念理解

    1.什么是进程?

            进程就是在某种程度上相互隔离,独立运行的程序。一般来说,系统都是支持多进程操作的,这所谓的多进程就是让系统好像同时运行多个程序。

    2.什么是线程呢?

           一个进程可以包含多个线程,在程序中是独立的,并发执行的流,但是与分隔的线程相比,进程中的线程之间的隔离程度要小。他们共享内存,文件句柄和每个线程应有的状态。

    3.进程和线程的区别:

         (1)一个进程可以包含多个线程,线程比进程具有更高的性能.

             这是因为多个线程将共享同一个进程的虚拟空间。线程共享的环境包括:线程代码块,进程的共有数据等。利用这些共享的数据,县城很容易实现相互间的通信。

         (2)进程间不能共享内存,线程间共享内存很容易。

         (3)系统创建进程需要为该进程分配系统资源,但创建线程则代价小的多,因此使用线程开始先多任务并发比多线程效率高。

    《二》线程的应用

    1.创建线程的方式一:通过Thread来实现。

    Thread()创建一个线程。

    Thread(Runnable targer):创建一个线程,并指定一个目标。

    Thread(String name ):创建一个名为name 的线程。

    Thread(ThreadGroup group ,Runnable targer):创建一个隶属于group线程组的线程。

    Thread(ThreadGroup group ,Runnable targer,String name):创建一个隶属于group线程组,目标为target,名字为name的线程。

    Thread(ThreadGroup group ,String name):创建一个名字为name,隶属于group的线程组。

    用Thread来实现多线程,还包括两种写法。

    (1)使用局部内部类的方式实现。如下:红色标记表示不同的地方,请注意看。

    public class TestThead {
    	public static void main(String[] args) {
    		//调用线程	
    		MyThread myThread = new MyThread();
    		//启动一个线程
    		myThread.start();
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程一");
    		}
    	}
    }
    //局部内部类的方式创建。继承Thread类重写run方法。
    class MyThread extends Thread {
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程二");
    		}
    	}
    }


    (2)直接继承Thread类。如下:

    public class TestThead2 extends Thread {
    	public static void main(String[] args) {
    		//创建本类的对象
    		TestThead2 testThead2 = new TestThead2();
    		//创建一个线程
    		Thread thread = new Thread(testThead2);
    		//启动一个线程
    		thread.start();
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程一");
    		}
    	}
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程二");
    		}
    	}
    }

    2.创建线程的方式二:通过Runnable接口实现多线程的创建。

    (1)使用局部内部类的方法

    public class TestThead3 {
    	public static void main(String[] args) {
    		// 启动线程
    		ThreeThread target = new ThreeThread();
    		Thread thread = new Thread(target);
    		thread.start();
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程一");
    		}
    	}
    }
    
    class ThreeThread implements Runnable {
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程二");
    		}
    	}
    


     

    (2)直接继承接口

    public class TestThead5 implements Runnable {
    	public static void main(String[] args) {
    		// 启动线程
    		ThreeThread5 target = new ThreeThread5();
    		Thread thread = new Thread(target);
    		thread.start();
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程一");
    		}
    	}
    
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程二");
    		}
    	}
    }
    

    3.两种创建线程的方法比较

    (1)使用Runnable接口

    可以将CPU,代码和数据分开,形成清晰的模型。
    使用接口后,该类还可以继承别的类。

    保持程序风格一致。

    (2) 使用Thread类

    不能再从其他类继承。

    编写简单,可以直接操作线程,无需使用Thread.currentThread().


    4.守护线程。

    有一种线程,他是从后台运行的,他的任务是为其他线程提供服务,这种线程被称为守护线程。 典型的案例:定时器(Timer)

    (1)setDaemon(boolean d):把普通线程设置为守护线程(又叫:后台线程)

    (2)isDaemon():测试特定线程是否是后台线程。

    例子如下:

    package com.zyy;
    // 线程的优先级
    public class MyDaemon {
    	public static void main(String[] args) {
    		Run run = new Run();
    		Thread th1 = new Thread(run);
    		th1.setDaemon(true);
    		System.out.println(th1.isDaemon());// 判断某个线程是不是守护线程。
    		th1.start();
    		for(int i=0;i<100;i++){
    			System.out.println(Thread.currentThread().getName()+"--"+i);
    		}
    	}
    }
    
    class Run implements Runnable{
    	@Override
    	public void run() {
    		while(true){
    			System.out.println("我是守护线程");
    		}
    	}
    }


    5.线程的状态

    进程可以分为五中状态:新建,就绪,运行,阻塞,死亡

    (1)当使用new来创建一个线程的时候,他处于new状态,这时候,线程并没有进行任何的操作。

    (2)当使用线程的start()方法时候,想线程调度程序注册一个线程,这个时候这个线程就就绪了,就等待CPU给他分配时间了。

    (3)调用线程的Run方法给已经注册的线程,执行的机会。进入运行状态。

    (4)当run方法执行完毕后,线程将被抛弃。进入死亡状态。

    (5)如果线程在运行状态中因为IO阻塞,等待键盘输入,调用线程的sleep(),wait()方法,线程就会进入阻塞状态,以上导致阻塞的因素消失了,如“输入结束”,则进入就绪状态,继续等待CPU分配的时间。

    6.线程的结束方式

    线程有三种结束方式:

    (1)运行到run方法的结尾,自动结束

    (2)线程抛出一个未捕获的异常

    (3)另一个线程调用Deprecate的stop()方法,由于这个方法会引起线程的不安全问题,所以已经不推荐使用了。

    7.线程的优先级

     getPriority()、setPriority得到和设置当前线程的优先级。优先级1-10,如果不指定默认是5.理论上,谁优先级高,谁被cpu调度的可能性就大。但是优先级低的并不是不执行。资源不足的时候才有效果。这个只是程序员实行的建议权。

    举个例子:

    public class TestProprity {
    	public static void main(String[] args) {
    		myRun myRun = new myRun();
    		Thread thread1 = new Thread(myRun,"乌龟4");
    		thread1.start();
    		thread1.setPriority(4);
    		Thread thread2 = new Thread(myRun,"乌龟10");
    		thread2.start();
    		thread2.setPriority(10);
    		Thread.currentThread().setName("兔子");
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程一"+Thread.currentThread().getName()+Thread.currentThread().getPriority());
    		}
    	}
    }
    class myRun implements Runnable
    {
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println("线程二"+Thread.currentThread().getName());
    		}
    		
    	}
    	
    }
    

    8.线程的其他常用方法。

    1.       sleep:让当前线程停止执行(休眠)一段时间。

    2.       join:如果在A线程中B线程join进来,则现在执行B的内容,直到B执行完毕才继续执行A。比如A是显示数据  B是收集收据。

    3.       yield:让位:让出执行权,和其他线程争夺资源,谁拿到cpu时间片谁执行。

    4.        wait:线程进入等待状态,等待notify()的唤醒。

    《三》定时器的应用

    public class TestTimer extends JFrame {
    	private static final long serialVersionUID = 1L;
    	private JLabel lbshow;
    	private int niIndex=2;
    
    	public TestTimer() {
    
    		JPanel basicJPanel = new JPanel();
    		basicJPanel.setLayout(new BorderLayout());
    		lbshow = new JLabel();
    		lbshow.setIcon(new ImageIcon("logo/1.png"));
    		basicJPanel.add(lbshow, BorderLayout.CENTER);
    		setContentPane(basicJPanel);
    		setBounds(200, 200, 410, 320);
    		setVisible(true);
    		Timer timer = new Timer();
    		myTimerTask task = new myTimerTask();
    		//第一参数:到了时间要执行的目标,二:多长时间之后开始进行计时。三:每隔1S执行一次。
    		timer.schedule(task,1000, 1000);
    	}
    
    	public class myTimerTask extends TimerTask {
    
    		@Override
    		public void run() {
    			// TODO Auto-generated method stub
    			if(niIndex<7) {
    				niIndex++;
    				lbshow.setIcon(new ImageIcon("logo/"+niIndex+".png"));
    				
    			}
    		}
    	}
    
    	public static void main(String[] args) {
    		new TestTimer();
    	}
    }
    


     

  • 相关阅读:
    modf()函数
    面向对象编程五大原则
    .Net网络资源
    整理CentOS常用命令
    在RHEL5上安装oracle10gLinux
    strchr()函数
    swab函数
    Strstr()函数
    tmpnam函数
    strdup ()函数
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3246659.html
Copyright © 2011-2022 走看看