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();
    	}
    }
    


     

  • 相关阅读:
    Chrome开发者工具中Elements(元素)断点的用途
    最简单的SAP云平台开发教程
    Java实现 LeetCode 495 提莫攻击
    Java实现 LeetCode 494 目标和
    Java实现 LeetCode 494 目标和
    Java实现 LeetCode 494 目标和
    Java实现 LeetCode 493 翻转对
    Java实现 LeetCode 493 翻转对
    Java实现 LeetCode 493 翻转对
    Java实现 LeetCode 492 构造矩形
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3246659.html
Copyright © 2011-2022 走看看