JAVA基础--线程

sleep和wait的区别:

1. sleep是Thread的方法, wait是object的方法

2.  sleep占着CPU睡觉, wait等待CPU,不占用CPU

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

线程和进程的区别:

1. 每个进程都有独立的代码和数据空间, 进程间的切换会有很大的开销.

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

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

4. 多线程:在同一个程序可以有多个顺序刘同时执行.

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

每个线程都通过特定Thread对象对应的run方法来完成操作, 方法run称为线程体

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

run是方法调用,start是开启一个线程

以下程序只有一个线程 main, 主线程

public class {
	public static void main(String[] args) {
		m1();
	}
	
	public static  void m1() {
		m2();
		m3();
	}
	
	public static void m2() {}
	public static void m3() {}
}

进程: 一个class文件, 一个exe文件, 是个静态的概念.进程的执行指的是一个主线程开始执行, 即main开始.

所以机器里我们运行的都是线程.

建议使用以下接口的方式:

 

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);
		}
	}
}

还有一种方法,继承Thread,不建议使用:

public class TestThread1 {
	public static void main(String args[]) {
		Runner1 r = new Runner1();
		r.start();
		for(int i=0; i<100; i++) {
			System.out.println("Main Thread:------" + i);
		}
	}
}

class Runner1 extends Thread {
	public void run() {
		for(int i=0; i<100; i++) {	
			System.out.println("Runner1 :" + i);
		}
	}
}

  

线程状态转换:

创建-->start-->就绪--> 运行-->终止  运行-->阻塞状态-->就绪 

线程控制的方法:

isAlive():  阻塞,运行, 就绪,  

getPriority() 获得优先级

setPriority(): 设置优先级

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

join(): 合并, 等改线程结束再恢复当前线程的运行

yield(): 让出CPU, 当前线程进去就绪状态等待调度

wait(): 当前线程进入wait pool

 

sleep方法: Thread类的静态方法:

import java.util.*;
public class TestInterrupt {
  public static void main(String[] args) {
    Runner r = new Runner();
    Thread t = new Thread(r);
    t.start();
    try {Thread.sleep(10000);}
    catch (InterruptedException e) {}
    //t.interrupt();  //打断子线程,比较粗暴
r.flag=false; //替换上面的打断子线程的方式, 用这种方式, run方法里的return也可以注释掉了 } } class Runner implements Runnable {    boolean flag = true;   public void run(){ while(flag){ System.out.println("==="+new Date()+"==="); try { Thread.sleep(1000); } catch (InterruptedException e) { //被打算后进入异常, return return; } } } }

结果:每隔一秒显示一次:

===Fri Apr 08 10:53:44 CST 2016===
===Fri Apr 08 10:53:45 CST 2016===
===Fri Apr 08 10:53:46 CST 2016===
===Fri Apr 08 10:53:47 CST 2016===
===Fri Apr 08 10:53:48 CST 2016===
===Fri Apr 08 10:53:49 CST 2016===
===Fri Apr 08 10:53:50 CST 2016===
===Fri Apr 08 10:53:51 CST 2016===
===Fri Apr 08 10:53:52 CST 2016===
===Fri Apr 08 10:53:53 CST 2016===

  

join用法:相当于调用, 如果main里调用join, 那么会等join的线程执行完才能执行自己的线程:

public class TestJoin {
  public static void main(String[] args) {
    MyThread2 t1 = new MyThread2("abcde");
    t1.start();
    try {
    	t1.join();
    } catch (InterruptedException e) {}
    	
    for(int i=1;i<=10;i++){
      System.out.println("i am main thread");
    }
  }
}
class MyThread2 extends Thread {
  MyThread2(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;
      }
    }
  }
}

结果:

i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am abcde
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread

  

yield方法: 让出CPU, 给其他线程执行的机会:

只要运行的线程 i 被10整除, 就让出给别的线程运行

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

  

线程的优先级:

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);
		}
	}
}
Thread.MIN_PRIORITY=1;

Thread.MAX_PRIORITY=10;

Thread.NORM_PRIORITY=5;

  

同一个线程对象可以定义两个Thread:

public class TestThread2 {
	public static void main(String args[]) {
		Runner2 r = new Runner2();
		Thread t1 = new Thread(r);
		Thread t2 = new Thread(r);
		t1.start();
		t2.start();
	}
}

class Runner2 implements Runnable {
	public void run() {
		for(int i=0; i<30; i++) {	
			System.out.println("No. " + i);
		}
	}
}

被10整除就停顿2s:

public class TestThread3{
	public static void main(String args[]) {
		Runner3 r = new Runner3();
		Thread t = new Thread(r);
		t.start();
	}
}

class Runner3 implements Runnable {
	public void run() {
		for(int i=0; i<30; i++) {	
			if(i%10==0 && i!=0) {
				try{
					Thread.sleep(2000); 
				}catch(InterruptedException e){}
			}
			System.out.println("No. " + i);
		}
	}
}

如何恰当的结束线程, 用flag:

public class TestThread4 {	
	public static void main(String args[]){
		Runner4 r = new Runner4();
       	Thread t = new Thread(r);
        t.start();
        for(int i=0;i<100000;i++){
        	if(i%10000==0 & i>0)
        		System.out.println("in thread main i=" + i);
        }
        System.out.println("Thread main is over");
        r.shutDown();
        //t.stop();
    }
}

class Runner4 implements Runnable {
  private boolean flag=true;
  
	public void run() {
		int i = 0;
		while (flag==true) {
			System.out.print(" " + i++);	
		}
	}
	
  public void shutDown() {
		flag = false;
  }
}

 

isAlive:

public class TestThread6 {	
	public static void main(String args[]){
		Thread t = new Runner6();
   		t.start();		
		for(int i=0; i<50; i++) {
			System.out.println("MainThread: " + i);
		}
  }
}

class Runner6 extends Thread {
	public void run() {
		System.out.println(Thread.currentThread().isAlive());
		for(int i=0;i<50;i++) {
			System.out.println("SubThread: " + i);
		}
	}
}

 

 线程同步: synchronized:

执行方法的过程中当前对象被锁定, 这样对象控制一个过程, 别的线程不可打扰.

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的线程");
	 //}
  }
}

结果:

不加synchronized的话, 就都显示2

t1, 你是第1个使用timer的线程
t2, 你是第2个使用timer的线程

  

 

用synchronize的时候会出现死锁的现象,比如线程A执行过程中,锁定某一个对象1.   另一个线程B锁定另一个对象2, 线程A 需要继续锁定对象2, 线程B需要锁定对象1, 就会发生死锁.

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();
		
	}
}

结果: 线程不动了:

flag=1
flag=0

 

线程锁死后, 别的方法还可以访问

public class TT implements Runnable {
	int b = 100;
	
	public synchronized void m1() throws Exception{
		b = 1000;
		Thread.sleep(5000);
		System.out.println("b = " + b);
	}
	
	public  void m2() {
		System.out.println(b);
	}
	
	public void run() {
		try {
			m1();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws Exception {
		TT tt = new TT();
		Thread t = new Thread(tt);
		t.start();
		Thread.sleep(1000);
		tt.m2();
	}
}

结果:

1000
b = 1000

 

上例子改一下:

public class TT implements Runnable {
	int b = 100;
	
	public synchronized void m1() throws Exception{
		b = 1000;
		Thread.sleep(5000);
		System.out.println("b = " + b);
	}
	
	public void m2() throws Exception {
		Thread.sleep(2500);
		b = 2000;
	}
	
	public void run() {
		try {
			m1();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws Exception {
		TT tt = new TT();
		Thread t = new Thread(tt);
		t.start();
		
		tt.m2();
		System.out.println(tt.b);
	}
}

结果:

2000
b = 2000

再改一下:

1. 先执行m2, 执行完后

2. m1 执行 b=1000;

3. 主线程执行 输出b

4. m1 执行 输出b=1000;

public class TT implements Runnable {
	int b = 100;
	
	public synchronized void m1() throws Exception{
		b = 1000;		
		Thread.sleep(5000);
		System.out.println("b = " + b);
	}
	
	public synchronized void m2() throws Exception {
		Thread.sleep(2500);
		b = 2000;
	}
	
	public void run() {
		try {
			m1();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws Exception {
		TT tt = new TT();
		Thread t = new Thread(tt);
		t.start();
		tt.m2();		
		System.out.println(tt.b);	
	}
}

结果:

1000
b = 1000

  

wait必须和synchronized同时出现, 不能单独使用wait, wait是object类的方法.

wait的时候锁不归我所有, sleep的时候, 还抱着锁.

wait后需要notify叫醒, 也是object类的方法

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(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<10; 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<10; i++) {
			WoTou wt = ss.pop();
			System.out.println("消费了: " + wt);
			try {
				Thread.sleep((int)(Math.random() * 1000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}			
		}
	}
}

  

  

  

  

  

posted @ 2016-04-06 19:57  wujixing909  阅读(157)  评论(0编辑  收藏  举报