一、什么是线程?
线程是一个程序内部的顺序控制流。
二、线程和进程的区别?
1、每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销。
2、线程可以看成是轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
3、多进程:在操作系统中能同时运行多个任务(程序)。
4、多线程:在同一应用程序中有多个顺序流同时执行。
三、线程的创建和启动
1、第一种:
(1)定义线程类实现Runnable接口。
Thread myThread = new Thread (target) //target为Runnable为接口类型
(2)Runnable中只有一个方法:
public void run(); //用于定义线程运行体
(3)使用Runnable接口可以为多个线程提供共享的数据。
(4)在实现Runnable接口的类的run方法定义中可以使用Thread的静态方法:
public static Thread currentThread() //获取当前线程的引用
2、第二种:
可以定义一个Thread的子类并重写其run方法如:
class MyThread extends Thread{
public void run(){...}
}
然后生成该类的对象:
MyThread myThread = new MyThread(...)
例子:
public class TestThread1{
public static void main(String args[]){
Runner1 r=new Runner1();
Thread t=new Thread(r);
t.start();
for(int i=0;i<100;i++){
System.out.println("Main Thread:----"+i);
}
}
}
class Runner1 implements Runnable{
public void run(){
for(int i=0;i<100;i++){
System.out.println("Runner1:"+i);
= }
}
}
四、线程状态转换:
五、线程控制基本方法:
六、线程的优先级别:
Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调用哪个线程来执行。
线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5。
Thread.Min_PRIORITY = 1
Thread.MAX_PRIORITY = 10
Thread.NORM_PRIORITY = 5
使用下述线方法获得或设置线程对象的优先级。
int getPriority();
void setPriority(int newPriority);
例子:
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 < 1000; i++) {
System.out.println("T1:" + i);
}
}
}
class T2 implements Runnable {
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("------T2:" + i);
}
}
}
七、线程同步
在Java语言中,引入了对象互斥锁的概念,保重共享数据操作的完整性。每个对象都应对于一个可称为“互斥锁”的标记,这个标记保证在任一时刻,只能有一个线程访问该对象。
关键字synchronized来与对象的互斥锁联系。当某个对象synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。
synchorized 的使用方法:
synchronized(this){
num++;
try { Thread.sleep(1); }
catch (InterruptedException e) { }
System.out.println
{ name + ",你是第" + num + "个使用timer的线程" };
}
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 void add(String name) {
synchronized(this){
num++;
try { Thread.sleep(1); }
catch (InterruptedException e) { }
System.out.println(name + ",你是第" + num + "个使用timer的线程");
}
}
}
八、生产者消费者问题:
public class ProducerConsumer {
public static void main(String[] args) {
SyncStack ss = new SyncStack();
Producer p = new Producer(ss);
Consumer c = new Consumer(ss);
new Thread(p).start();
new Thread(p).start();
new Thread(p).start();
new Thread(c).start();
}
}
class WoTou {
int id;
WoTou(int id) {
this.id = id;
}
public String toString() {
return "WoTou : " + id;
}
}
class SyncStack {
int index = 0;
WoTou[] arrWT = new WoTou[6];
public synchronized void push(WoTou wt) {
while(index == arrWT.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
arrWT[index] = wt;
index ++;
}
public synchronized WoTou pop() {
while(index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
index--;
return arrWT[index];
}
}
class Producer implements Runnable {
SyncStack ss = null;
Producer(SyncStack ss) {
this.ss = ss;
}
public void run() {
for(int i=0; i<20; i++) {
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生产了:" + wt);
try {
Thread.sleep((int)(Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
SyncStack ss = null;
Consumer(SyncStack ss) {
this.ss = ss;
}
public void run() {
for(int i=0; i<20; i++) {
WoTou wt = ss.pop();
System.out.println("消费了: " + wt);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}