Thread-线程

来源:互联网 发布:java sock5 编辑:程序博客网 时间:2024/05/19 05:33

线程是程序里不同的执行路径

起一个新的线程,执行在run方法里面的程序


一、构造方法

推荐用实现接口,因为继承只能单继承

1.实现Runnable接口

package threadText;public class TestThread1 {public static void main(String[] args){Runner1 r = new Runner1();//r.run();这样是方法的调用,不是线程Thread t = new Thread(r);//必须实例化一个Threadt.start();//必须调用start开始一个新的线程for(int i=0; i<100; i++){System.out.println("main"+ i);}}}class Runner1 implements Runnable{//比如重写run方法public void run(){for(int i=0; i<100; i++){System.out.println("Runner" + i);}}}

2.继承Thread类

package threadText;public class TestThread2 {public static void main(String[] args){Runner2 r = new Runner2();r.start();//因为r本身就是Thread类,所以可以直接调用for(int i = 0; i<100; i++){System.out.println("Main:" + i);}}}class Runner2 extends Thread{//继承Thread类public void run(){for(int i=0; i<100; i++){System.out.println("Runner" + i);}}}


二、sleep、join、 yeild方法

1.sleep方法

线程退出的一种方式,但是更好的方法是写一个flag

Thread静态方法,会抛出被打断的异常
package threadText;import java.util.*;public class TestInterrupt {public static void main(String[] args){MyThread thread = new MyThread();thread.start();try{Thread.sleep(10000);//使主进程暂睡眠}catch(InterruptedException e){}thread.interrupt();//打断子进程}}class MyThread extends Thread{public void run(){while(true){System.out.println("===" + new Date() + "===");try{sleep(1000);} catch (InterruptedException e){return;//如果被打断结束子进程}}}}

2.join方法

合并某个线程

package threadText;public class TestJoin {public static void main(String[] args){MyThread2 t2 = new MyThread2("abcd");t2.start();try{t2.join();//将t2合并到线程,即执行完t2才执行主线程}catch(InterruptedException e){}for(int i = 0; i<10; i++){System.out.println("i am main Thread!");}}}class MyThread2 extends Thread{MyThread2(String s){//构造方法,把s传递给super即Thread名称super(s);}public void run(){for(int i = 0; i<10; i++){System.out.println("i am:" + getName() );//getName是Thread里的方法try{sleep(1000);}catch(InterruptedException e){return;}}}}

结果会执行完t2再执行主线程

3.yield方法

让出cpu让别的先执行

4.设置优先级

package threadText;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("This is T1"+ i);}}}class T2 implements Runnable{public void run(){for(int i = 0; i<100; i++){System.out.println("T2" + i);}}}

三、线程同步

一个线程在执行的过程中不会被另一个线程打断

package threadText;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();//两个访问的都是同一个timer文件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(100);}catch(InterruptedException e){}System.out.println(name+ "当前是第"+ num + "使用timer线程的");}}}

锁定了当前的对象后,,睡眠的时候别的进程也不会再执行,不会再出现混乱

死锁

锁定时粒度太小,会使线程无法结束
/* * 死锁的产生是因为两个线程锁住对方完成的条件之一 * 解决方法增加锁的粒度,即把整个方法都锁住,而不要锁小的方法 */package threadText;public class DeadLock implements Runnable{public int flag = 1;static Object o1 = new Object();static Object o2 = new Object();public void run(){//重写run方法System.out.println("flag:" + flag);if(flag == 1){//用if区别两个线程的run方法synchronized(o1){try{Thread.sleep(10000);}catch(Exception e){e.printStackTrace();}synchronized(o2){System.out.println("1");//在锁死o2该线程完成}}}if(flag == 0){synchronized(o2){//上来就把o2锁住,两个线程谁也无法完成try{Thread.sleep(10000);}catch(Exception e){e.printStackTrace();}synchronized(o1){System.out.println("0");}}}}public static void main(String[] args){DeadLock td1 = new DeadLock();DeadLock td2 = new DeadLock();td1.flag = 1;td2.flag = 0;Thread t1 = new Thread(td1);Thread t2 = new Thread(td2);t1.start();t2.start();}}

四、生产者消费者问题


package threadText;public class ProducerConsumer {public static void main(String[] args){SynStack ss = new SynStack();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(){//重写toString方法,方便显示return "WoTou" + id;}}class SynStack{//先进后出,用栈模拟篮子int index = 0;WoTou[] arrMT = new WoTou[6];public synchronized void push(WoTou wt){//同步,防止这个方法两条语句打断while(index == arrMT.length){//篮子满了就停止try{this.wait();//当前锁定在这个对象的线程停止,必须是锁定了以后才能wait}catch(InterruptedException e){e.printStackTrace();}}this.notify();//叫醒正在wait上的线程arrMT[index] = wt;index++;}public synchronized WoTou pop(){//取馒头while(index == 0){//没有馒头了等待try{this.wait();}catch(InterruptedException e){e.printStackTrace();}}this.notify();index--;return arrMT[index];}}class Producer implements Runnable{//生产者类SynStack ss = null;Producer(SynStack 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(1000);}catch(InterruptedException e ){e.printStackTrace();}}}}class Consumer implements Runnable{//生产者类SynStack ss = null;Consumer(SynStack 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(1000);}catch(InterruptedException e ){e.printStackTrace();}}}}


0 0
原创粉丝点击