标签:
创建线程 通过以下两种方法创建 Thread 对象: 声明一个 Thread 类的子类,并覆盖 run() 方法。 class mythread extends Thread { public void run( ) {/* 覆盖该方法*/ } } 声明一个实现 Runnable 接口的类,并实现 run() 方法。 class mythread implements Runnable{ public void run( ) {/* 实现该方法*/ } }
一. Thread 类
在Java程序启动时,一个线程立刻运行,该线程通常称为程序的主线程。
主线程的重要性体现在两个方面:
它是产生其他子线程的线程。
通常它必须最后完成执行,因为它执行各种关闭动作。
线程的使用场合
用于处理时间比较久的积序
用于IO的阻塞操作
Thread常用方法
重要方法 start() 启动线程; setPriority(int p) 设置线程的优先级; interrupt() 有条件中断线程; sleep(long s) (static)使线程睡眠;让出cpu资源; currentThread() (static)获取当前正在执行的线程; isAlive() 判断线程是否在活动状态; yield() 让出cpu资源; setDaemon(boolean b) 是否是守护线程; jion() 等待线程消亡;
举例代码:
public class TestExtendThread extends Thread { public void run() { while(true){ System.out.println("Run方法 " ); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { // 主线程可以创建其他子线程 TestExtendThread thread = new TestExtendThread(); thread.start(); //开启线程 for (int i = 0; i < 100; i++){ System.out.println("Main主线程" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
运行结果:
Run方法
Main主线程0
Run方法
Main主线程1
Run方法
Main主线程2
Run方法
Main主线程3
Run方法
Main主线程4
Run方法
二. 实现Runnable接口
实现Runnable接口 public class ImplRunnable implements Runnable{ public void run(){ //线程要执行的代码 } } 创建并启动线程 ImplRunnable ir = new ImplRunnable(); Thread thread = new Thread(ir); thread.start();
举例代码:
public class TestRunable implements Runnable { public void run() { //接口Runnable的实现方法重写 while(true){ System.out.println("Run方法 " ); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { TestRunable runnable = new TestRunable(); Thread thread = new Thread(runnable); thread.start(); for (int i = 0; i < 100; i++){ System.out.println("Main主线程" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
运行结果:
Run方法
Main主线程0
Main主线程1
Run方法
Run方法
Main主线程2
Run方法
Main主线程3
Main主线程4
Run方法
Run方法
Main主线程5
Run方法
Main主线程6
Run方法
Main主线程7
线程的状态图
join() 方法 :
join()
等待该线程终止。
未使用join前
public class Testjoin { public static void main(String[] args){ Testone one = new Testone(); Testtwo two = new Testtwo(); one.start(); two.start(); for(int i = 0; i < 100; i++){ System.out.println("Main主线程" + i); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Testone extends Thread{ public void run(){ while (true) { System.out.println("线程1"); try { Thread.sleep(200); } catch (Exception e) { e.printStackTrace(); } } } } class Testtwo extends Thread{ public void run() { while (true) { System.out.println("线程2"); try { Thread.sleep(200); } catch (Exception e) { e.printStackTrace(); } } } }
运行结果:
Main主线程0
线程1
线程2
线程1
线程2
Main主线程1
线程2
Main主线程2
线程1
线程2
线程1
Main主线程3
线程1
线程2
Main主线程4
线程2
线程1
Main主线程5
线程2
线程1
........
使用join方法:
public class Testjoin { public static void main(String[] args){ Testone one = new Testone(); Testtwo two = new Testtwo(); /* * 在one.start后面使用one.join方法 * 将等待该进程完成后再继续其他进程的使用 */ one.start(); try { one.join(); } catch (InterruptedException e1) { e1.printStackTrace(); } two.start(); for(int i = 0; i < 100; i++){ System.out.println("Main主线程" + i); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Testone extends Thread{ public void run(){ for (int i = 0; i < 10; i++) { System.out.println("线程1"); try { Thread.sleep(200); } catch (Exception e) { e.printStackTrace(); } } } } class Testtwo extends Thread{ public void run() { while (true) { System.out.println("线程2"); try { Thread.sleep(200); } catch (Exception e) { e.printStackTrace(); } } } }
运行结果:
线程1
线程1
线程1
线程1
线程1
线程1
线程1
线程1
线程1
线程1
线程2
Main主线程0
线程2
Main主线程1
线程2
Main主线程2
线程2
Main主线程3
线程2
同样的,yield() 方法 暂停当前正在执行的线程对象,并执行其他线程。也就是说作用于join相反
线程的优先级 Java 中的线程优先级是在 Thread 类中定义的常量: NORM_PRIORITY : 值为 5 MAX_PRIORITY : 值为 10 MIN_PRIORITY : 值为 1 缺省优先级为 NORM_PRIORITY 有关优先级的方法有两个: final void setPriority(int newPriority ) : 修改线程的当前优先级 final int getPriority() : 返回线程的优先级
二. 停止线程
可能使线程暂停执行的条件
线程优先级比较低,因此它不能获得 CPU 时间。
使用 sleep( ) 方法使线程睡眠。
通过调用 wait( ) 方法,使线程等待。
通过调用 yield( ) 方法,线程已显式出让CPU控制权。
线程由于等待一个文件I/O事件被阻塞。
结束线程
尽量不使用stop()或者destroy()方法来结束线程,可能会产生死锁,应尽量让线程中run方法运行正常结束的方法
结束线程可以使用以下三种方法:
修改标志
interrupt()
引发异常
方法一:修改标志
package com.study233; public class StopThread_flag extends Thread { private boolean isStop = false; public void run(){ while (this.isStop == false){ System.out.println("线程运行"); } try { Thread.currentThread().sleep(100); } catch (Exception e) { e.printStackTrace(); } } public void shopThread(){ this.isStop = false; try { this.join(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args){ StopThread_flag stf = new StopThread_flag(); stf.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } stf.shopThread(); } }
运行结果:
线程运行
线程运行
线程运行
线程运行
线程运行
线程运行
线程运行
线程运行
线程运行
线程运行
线程运行
线程停止!
方法二:interrupt()
适用于睡眠或者等待 public void run(){ while(!this.isInterrupted()){ try { Thread.sleep(2000); } catch (InterruptedException e) { return; } } } 此类线程只要调用interrupt()方法就可以终止线程。
方法三:引发异常
适用于阻塞(如监听连接,读网络上发来的数据) public void run(){ byte[] buf = new byte[2048]; int len; while(true){ try{ //bi是缓冲输入流 len = bi.read(buf); //其他代码 }catch(IOException e){ //异常处理 break; //跳出循环,线程也就结束。 } } }
三. 线程同步问题
并发访问问题
有时两个或多个线程可能会试图同时访问一个资源 例如,一个线程可能尝试从一个文件中读取数据,而另一个线程则尝试在同一文件中修改数据。 例如,100个线程同时往一个帐户存钱。 在此情况下,数据可能会变得不一致 那如何解决这个问题呢?
如果同步: 同步基于“监视器”这一概念。“监视器”是用作互斥锁的对象;在给定时刻,只有一个线程可以拥有监视器。Java中所有的对象都拥有自己的监视器。 两种方式实现同步: 使用同步方法 synchronized void methodA() { } 使用同步块 synchronized(object) { //要同步的语句 }
锁的概念:
对象锁,锁住该方法或者该变量所在的对象或者类
方法同步一:synchronized void methodA() { }
class Testone extends Thread{ public synchronized void run(){ for (int i = 0; i < 10; i++) { System.out.println("线程1" + i); try { Thread.sleep(200); } catch (Exception e) { e.printStackTrace(); } } } }
方法同步二:使用同步块
标签:
原文地址:http://www.cnblogs.com/hlwyfeng/p/4435708.html