标签:
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.同步方法
同步方法是指使用synchronized关键字修饰的方法,进入同步方法执行的线程将获得同步方法所属对象的锁,一旦锁住,只有该线程执行完,其他线程才能执行,因此保证了方法同步的安全性。
<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.总结
本篇文章简单的总结了线程中的一些概念,但是这些概念是以后开发高级线程必备的知识,需要多理解。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/luckyzhoustar/article/details/46686081