Java总结之线程

【线程的基本概念】

线程是一个程序内部的顺序控制流。

线程和进程的区别:

每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销。

线程可以看成是轻量级的进程,同一类线程共享代码和数据空间,每个县城有独立的运行站和程序计数器(PC),线程切换的开销小。

多进程:在操作系统中能同时运行多个任务(程序)

多线程:在同一应用程序中有多个顺序流同时执行

Java的线程是通过java.lang.Thread类来实现的。

VM启动时会有一个由主方法(public static void main(){})所定义的线程。

可以通过创建Thread的实例来创建新的线程。

每个线程都是通过摸个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。

通过调用Thread类的start()方法来启动一个线程。

【线程控制基本方法】

isAlive() 判断线程是否还“活”着,即线程是否还未终止。

getPriority() 获得线程的优先级数值

setPriority() 设置现成的优先级数值

Thread.sleep() 将当前线程睡眠指定毫秒数

join() 调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行。

yield() 让出CPU,当前线程进入就绪队列等待调度。

wait() 当前线程进入对象的wait pool。

notify()/notifyAll() 唤醒对象的wait pool中的一个/所有等待线程。

【sleep/join/yield方法】

sleep方法

可以调用Thread的静态方法:

public static void sleep(long millis) throws InterruptedExcepion

使得当前线程休眠(暂时停止执行millis毫秒)

由于是静态方法,sleep可以由类名直接调用:

Thread.sleep(...)

join方法

合并某个线程

yield方法

让出CPU,给其他线程执行的机会

join范例:

public class TestJoin extends Thread{
	public static void main(String[] args) {
		MyThread t1 = new MyThread("t1");
		t1.start();
		try {t1.join();}
		catch (InterruptedException e) {}
		for(int i=1;i<=10;i++) {
			System.out.println("i am main thread");
		}
	}
}
class MyThread extends Thread {
	MyThread(String s) {super(s);}
	public void run() {
		for(int i=1;i<=10;i++) {
			System.out.println("i am "+getName());
			try {sleep(1000);}
			catch (InterruptedException e) {return;}
		}
	}
}

yield范例:

public class TestYield {
	public static void main(String[] args) {
		MyThread t1 = new MyThread("t1");
		MyThread t2 = new MyThread("t2");
		t1.start(); t2.start();
	}
}
class MyThread extends Thread {
	MyThread(String s) {super(s);}
	public void run() {
		for(int i=1;i<=100;i++) {
			System.out.println(getName()+": "+i);
			if(i%10==0) {
				yield();
			}
		}
	}
}

【线程的优先级别】

Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度那个线程来执行。

线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5.

Thread.MIN_PRIORITY = 1

Thread.MAX_PRIORITY = 10

Thread.NORM_PRIORITY = 5

使用下述方法获得或设置线程对象的优先级。

int getPriority();

void setPriority(int new Priority);

Priority范例:

public class TestPriority {
	public static void main(String[] args) {
		Thread t1 = new Thread(new T1());
		Thread t2 = new Thread(new T2());
		t1.setPriority(Thread.NORM_PRIORITY + 3);
		t1.start();
		t2.start();
	}
}
class T1 implements Runnable {
	public void run() {
		for(int i=0;i<100;i++) {
			System.out.println("T1: "+i);
		}
	}
}
class T2 implements Runnable {
	public void run() {
		for(int i=0;i<100;i++) {
			System.out.println("------T2: "+i);
		}
	}
}

【线程同步】

在Java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性。每个对象都对应于一个可称为"互斥锁"的标记,这个标记保证在任意时刻,只能有一个线程访问该对象。

关键字synchronized来与对象互斥锁联系。当某个对象synchronized修饰时,表明该对象在任意时刻只能由一个线程访问。

synchronized 的使用方法:

synchronized(this) {...}

synchronized还可以放在方法声明中,表示整个方法为同步方法,例如:

synchronized public void add(String name) {...}

范例:

public class TestSync implements Runnable {
	Timer timer = new Timer();
	public static void main(String[] args) {
		TestSync test = new TestSync();
		Thread t1 = new Thread(test);
		Thread t2 = new Thread(test);
		t1.setName("t1");
		t2.setName("t2");
		t1.start();
		t2.start();
	}
	public void run() {
		timer.add(Thread.currentThread().getName());
	}
}
class Timer {
	private static int num = 0;
	public synchronized void add(String name) {
		//synchronized (this) {
			num ++;
			try {Thread.sleep(1);}
			catch (InterruptedException e) {}
			System.out.println(name+", 你是第"+num+"个使用timer的线程");
		//}
	}
}

【死锁】

范例:

public class TestDeadLock implements Runnable {
	public int flag = 1;
	static Object o1 = new Object(), o2 = new Object();
	public void run() {
		System.out.println("flag=" + flag);
		if(flag == 1) {
			synchronized(o1) {
				try {Thread.sleep(500);}
				catch (Exception e) {
					e.printStackTrace();
				}
				synchronized(o2) {
					System.out.println("1");
				}
			}
		}
		if(flag == 0) {
			synchronized(o2) {
				try {Thread.sleep(500);}
				catch (Exception e) {
					e.printStackTrace();
				}
				synchronized(o1) {
					System.out.println("0");
				}
			}
		}
	}
	public static void main(String[] args) {
		TestDeadLock td1 = new TestDeadLock();
		TestDeadLock td2 = new TestDeadLock();
		td1.flag = 1;
		td2.flag = 0;
		Thread t1 = new Thread(td1);
		Thread t2 = new Thread(td2);
		t1.start();
		t2.start();
	}
}

时间: 2024-10-27 11:14:01

Java总结之线程的相关文章

Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start(); 1 2 3 4 5 6 7 new Thread(new

java进阶07 线程的让步与阻塞与同步

前面介绍了线程的一些基本知识,现在来说下线程的让步,阻塞,和同步 先说说让步 所谓让步,就是让调用者的线程暂停,让其他线程重新竞争CPU,包括调用者. 先看看代码 package Thread; public class ThreadYield { public static void main(String[] args){ MyThread5 rthread=new MyThread5(); Thread thread1=new Thread(rthread); Thread thread2

java进阶06 线程初探

线程,程序和进程是经常容易混淆的概念. 程序:就是有序严谨的指令集 进程:是一个程序及其数据在处理机上顺序执行时所发生的活动 线程:程序中不同的执行路径,就是程序中多种处理或者方法. 线程有两种方法实现 一:继承Thread 覆盖run方法 package Thread; public class Thread1 { public static void main(String[] args){ MyThread1 thread1=new MyThread1(); thread1.setName

Java四种线程池

Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor 时间:2015-10-20 22:37:40      阅读:8762      评论:0      收藏:0      [点我收藏+] 介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异

Java中的线程池

综述 在我们的开发中经常会使用到多线程.例如在Android中,由于主线程的诸多限制,像网络请求等一些耗时的操作我们必须在子线程中运行.我们往往会通过new Thread来开启一个子线程,待子线程操作完成以后通过Handler切换到主线程中运行.这么以来我们无法管理我们所创建的子线程,并且无限制的创建子线程,它们相互之间竞争,很有可能由于占用过多资源而导致死机或者OOM.所以在Java中为我们提供了线程池来管理我们所创建的线程. 线程池的使用 采用线程池的好处 在这里我们首先来说一下采用线程池的

java多线程之线程的优先级

在操作系统中,线程可以划分优先级,优先级较高的线程得到CPU资源较多,也就是CPU优先执行优先级较高的线程对象中的任务(其实并不是这样). 在java中,线程的优先级用setPriority()方法就行,线程的优先级分为1-10这10个等级,如果小于1或大于10,则抛出异常throw new IllegalArgumentException(),默认是5. public class MyThread1 extends Thread { @Override public void run() {

初解Java中的线程

线程与进程的区别: 进程(process)本质上是一个执行的程序,每个进程有独立的代码和数据空间.基于进程的多任务处理的特点是允许你的计算机同时运行两个或更多的程序.举例来说,就是你的电脑在运行QQ的同时还可以飞信等其它应用程序.在基于进程的多任务处理中,程序是调度程序所分派的最小代码单位. 线程(thread-based) 是一个程序内部的顺序控制流.可以看成是轻量的进程,同一线程共享代码和数据空间.简单来说就是你用酷狗听着音乐,同时还可以搜索自己喜欢的歌. 线程的优先级: Java给每个线程

Java笔试题-线程编程方面

Ja 线程编程方面 60.java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 答:有两种实现方法,分别是继承Thread类与实现Runnable接口 用synchronized关键字修饰同步方法 反对使用stop(),是因为它不安全.它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们.结果很难检查出真正的问题所在.suspend()方法容易发生死锁.调用suspend()的时候,

浅谈利用同步机制解决Java中的线程安全问题

我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等着前面千百万人挑选购买,最后心仪的商品下架或者售空......假如饿了吗是单线程程序,那么一个用户得等前面全国千万个用户点完之后才能进行点餐,那饿了吗就该倒闭了不是吗?以上两个简单的例子,就说明一个程序能进行多线程并发访问的重要性,今天就让我们去了解一下Java中多线程并发访问这个方向吧. **第一

Java中的线程的生命周期大体可分为5种状态

Java中的线程的生命周期大体可分为5种状态. ①NEW:这种情况指的是,通过New关键字创建了Thread类(或其子类)的对象 ②RUNNABLE:这种情况指的是Thread类的对象调用了start()方法,这时的线程就等待时间片轮转到自己这,以便获得CPU:第二种情况是线程在处于RUNNABLE状态时并没有运行完自己的run方法,时间片用完之后回到RUNNABLE状态:还有种情况就是处于BLOCKED状态的线程结束了当前的BLOCKED状态之后重新回到RUNNABLE状态. ③RUNNING