zoukankan      html  css  js  c++  java
  • Java学习笔记五(多线程)

     

     1.介绍

    线程可以使程序具有两条和两条以上的可运行的路径。尤其对多核CPU特别的重要。


     2.创建线程

    1.继承Thread类

    一个类直接的继承Thread类的话,此类就具有了线程的能力,接下来仅仅须要重写继承的run()就可以。

    <span style="font-size:18px;">package com.Thread;
    
    
    //定义实现Runnable接口的类
    class MyThread11 extends Thread
    {
    	//实现run方法。指定线程运行的任务
    	public void run()
    	{
    		
    		System.out.println("启动一个线程!");
    	}
    }
    //主类
    public class Sample16_2
    {
    	public static void main(String[] args)
    	{
    		//继承Thread的类创建线程对象
    		
    		Thread t=new MyThread11();
    		//启动线程
    		t.start();
    		System.out.println("启用线程了");
    	}
    }
    </span>


    2.实现Runnable接口

    java採用的单继承,假设採用继承Thread类的话,会有非常多限制,因此常常採用的是继承Runnable接口来实现线程的创建。

    <span style="font-size:18px;">package com.Thread;
    
    //定义实现Runnable接口的类
    class MyRunnable implements Runnable
    {
    	//实现run方法。指定线程运行的任务
    	public void run()
    	{
    		
    		System.out.println("恭喜你。线程被启动了,"
    		               +"运行了run方法中的代码!

    。。"); } } //主类 public class Sample16_1 { public static void main(String[] args) { //创建实现Runnable接口的类的对象 MyRunnable mr=new MyRunnable(); //创建Thread对象,将第一步创建对象的引用作为构造器參数 //传递,指定线程要运行的任务 Thread t=new Thread(mr); //启动线程 t.start(); System.out.println("启用线程了"); } } </span>



     3.线程的同步

    1.同步方法

    同步方法是指使用synchronizedkeyword修饰的方法,进入同步方法运行的线程将获得同步方法所属对象的锁,一旦锁住。仅仅有该线程运行完,其它线程才干运行。因此保证了方法同步的安全性。

    <span style="font-size:18px;">package com.Thread;
    //资源类
    class Resource
    {
    	synchronized void function1(Thread currThread)
    	{
    		System.out.println(currThread.getName()+
    		"线程运行function1方法。!

    !"); try { Thread.sleep(1000); System.out.println(currThread.getName() +"线程睡醒了!

    "); } catch(Exception e) { e.printStackTrace(); } } synchronized void function2(Thread currThread) { System.out.println(currThread.getName()+ "线程运行function2方法!!

    !"); } } //自己定义线程类 class MyThread00 extends Thread { //资源对象的引用 Resource rs; //构造器 public MyThread00(String tName,Resource rs) { this.setName(tName); this.rs=rs; } public void run() { if(this.getName().equals("Thread1")) {//假设线程名称是Thread1訪问资源的function1方法 rs.function1(this); } else {//假设线程名称不是Thread1訪问资源的function2方法 System.out.println("Thread2启动。等待进入同步方法function2。。!"); rs.function2(this); } } } //主类 public class Sample16_8 { public static void main(String args[]) { Resource rs=new Resource(); MyThread00 t1=new MyThread00("Thread1",rs); MyThread00 t2=new MyThread00("Thread2",rs); t1.start(); try { Thread.sleep(10); } catch(Exception e) { e.printStackTrace(); } t2.start(); } } </span>


    注意:一个对象能够有同步和非同步方法,仅仅有进入同步方法运行才须要获得锁。每一个对象仅仅有一把锁;若一个对象有多个同步的方法,当某线程訪问当中之中的一个的时候。其它线程不能訪问该对象重点额不论什么同步方法。若线程获得锁后进入睡眠或让步,则将带着锁一块睡眠或让步。


    2.同步语句块

    使用同步语句块能够提高程序的并发性,能够精确的确定同步的区域。

    <span style="font-size:18px;">package com.Thread;
    
    //自己定义的线程类
    class MyThread33 extends Thread 
    {
    	//该引用为资源对象
    	private Object resource;
    	//无參构造器
    	public MyThread33()
    	{}
    	//有參构造器
    	public MyThread33(Object resource,String name)
    	{
    		//对线程进行初始化
    		this.resource=resource;
    		this.setName(name);
    	}
    	public void run()
    	{
    		//同步语句块
    		synchronized(resource)
    		{
              System.out.println(this.getName()
              +"线程訪问了资源!

    !。"); System.out.println(this.getName() +"线程带着锁睡觉去了!

    !。"); try { Thread.sleep(1000); } catch(Exception e) { e.printStackTrace(); } System.out.println(this.getName() +"线程带着锁睡醒后释放了锁!!!

    "); } } } //主类 public class Sample16_10 { public static void main(String[] args) { //创建资源对象 Object resource=new Object(); //创建2个线程 MyThread33 mt1=new MyThread33(resource,"MT1"); MyThread33 mt2=new MyThread33(resource,"MT2"); //启动这2个线程 mt1.start(); mt2.start(); } } </span>


    注意:当中synchronized(XXX),XXX代表的是资源对象的引用。


     4.线程的其它设置

    1.线程的优先级

    java中线程的优先级用1到10之间的整数表示,数值越大优先级越高。获得訪问CPU的机会越大。一般採用setPriority方法来设置。

    <span style="font-size:18px;">package com.Thread;
    
    //定义继承Thread的类
    class MyThread1 extends Thread {
    	// 重写run方法,指定该线程运行的代码
    	public void run() {
    		for (int i = 0; i <= 49; i++) {
    			System.out.print("<Min" + i + "> ");
    		}
    	}
    }
    
    // 定义另外一个继承Thread的类
    class MyThread2 extends Thread {
    	// 重写run方法,指定该线程运行的代码
    	public void run() {
    		for (int i = 0; i <= 49; i++) {
    			System.out.print("[Max" + i + "] ");
    		}
    	}
    }
    
    // 主类
    public class Sample16_4 {
    	public static void main(String[] args) {
    		// 创建两个线程对象
    		MyThread1 t1 = new MyThread1();
    		MyThread2 t2 = new MyThread2();
    		// 设置两个线程的优先级
    		t1.setPriority(Thread.MIN_PRIORITY);
    		t2.setPriority(Thread.MAX_PRIORITY);
    		// 启动两个线程
    		t1.start();
    		t2.start();
    
    	}
    }
    </span>


    2.线程的让步

    在实际开发中有时候也须要让某线程让出CPU。使其它线程得意运行。这时候能够採用让步的操作。

    一般调用yield方法。

    <span style="font-size:18px;">package com.Thread;
    
    //定义Runnable的实现类
    class MyRunnable1 implements Runnable
    {
    	//声明标识线程的两个字符串
    	private String flagl;
    	private String flagr;
    	//MyRunnable的构造器
    	public MyRunnable1(String flagl,String flagr)
    	{
    		//初始化标识字符串
    		this.flagl=flagl;
    		this.flagr=flagr;
    	}	
    	//重写run方法,指定该线程运行的代码
    	public void run()
    	{
    		for(int i=0;i<30;i++)
    		{
    			System.out.print(flagl+i+flagr);
    			//调用yield方法使当前正在运行的线程让步
    			Thread.yield();
    		}
    	}
    }
    //主类
    public class Sample16_5
    {
    	public static void main(String[] args)
    	{
    		//创建两个实现Runnable接口的类的对象
    		MyRunnable1 mr1=new MyRunnable1("[","] ");
    		MyRunnable1 mr2=new MyRunnable1("<","> ");
    		//创建两个线程Thread对象,并指定运行的target
    		Thread t1=new Thread(mr1);
    		Thread t2=new Thread(mr2);
    		//启动线程t1、t2
    		t1.start();	
    		t2.start();	
    	}
    }
    </span>


     5.总结

    本篇文章简单的总结了线程中的一些概念,可是这些概念是以后开发高级线程必备的知识,须要多理解。




  • 相关阅读:
    自我介绍
    币值转换
    打印沙漏
    对我影响最大的三位老师

    pta
    pta-3
    学习计划
    对我有影响的三个老师
    介绍自己
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7346212.html
Copyright © 2011-2022 走看看