JavaSE入门学习51:多线程编程(二)

       二Java多线程

       (4)线程的状态

       线程状态转换示意图:

JavaSE入门学习51:多线程编程(二)_第1张图片

       线程控制的基本方法:

JavaSE入门学习51:多线程编程(二)_第2张图片

       1)sleep()方法

       可以调用Thread的静态方法:

       public static void sleep(long millis) throws interruptedException

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

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

       thread.sleep(...)

       实例:

       打印十次当前日期时间

<span style="font-size:18px;">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){}
                //中断线程,不建议使用stop()方法
                thread.interrupt();
        }
}

class MyThread extends Thread{
    boolean flag = true;
	
    public void run(){
	    while(flag){
		System.out.println("==="+new Date()+"===");
                 try{
		     sleep(1000);
                 }catch(InterruptedException e){
		     return;
                 }
            }
    }
}</span>

       运行结果:

JavaSE入门学习51:多线程编程(二)_第3张图片

       打印两次间隔5秒的目前时间然后结束

<span style="font-size:18px;">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){}
		//中断线程,不建议使用stop()方法
                thread.interrupt();
       }
}

class MyThread extends Thread{
	boolean flag = true;
	
       public void run(){
		while (flag){
			String temp = new Date().toString();
                        String t = temp.substring(11, temp.indexOf('C'));
                        t = t.trim();
                        String[] time = t.split(":");
                        if(time.length == 3){
				System.out.println("现在是:" + time[0] + "点" + time[1] + "分" + time[2] + "秒");
                        }
                       try{
				Thread.sleep(5000);
                       }catch(InterruptedException e){
			    return;
                      }  
              }
      }
}</span>

       运行结果


       2)join()方法

       join()方法用于合并某个线程,也就是等着线程1执行完毕后,主线程才会执行。

<span style="font-size:18px;">public class TestJoin {
    public static void main(String[] args){
		MyThread2 t1 = new MyThread2("线程1");
                t1.start();
                try{
			t1.join();
                }catch(InterruptedException e) {}
    	
                for(int i=1;i<=10;i++){
                    System.out.println("主线程");
               }
    }
}

class MyThread2 extends Thread {
     MyThread2(String s){
		super(s);
     }
  
    public void run(){
            for(int i =1;i<=10;i++){
		 System.out.println("我是:"+getName());
                 try{
			sleep(1000);
                  }catch(InterruptedException e) {
      	                return;
                 }
            }
    }
}</span>

       运行结果:

JavaSE入门学习51:多线程编程(二)_第4张图片

       3)yield()方法

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

<span style="font-size:18px;">public class TestYield {
	public static void main(String[] args) {
		MyThread3 t1 = new MyThread3("线程1");
                MyThread3 t2 = new MyThread3("线程2");
                t1.start(); 
		t2.start();
        }
}


class MyThread3 extends Thread {
	MyThread3(String s){
		super(s);
	}
	
        public void run(){
		for(int i =1;i<=20;i++){
			System.out.println(getName()+": "+i);
                        if(i%10==0){
                              yield();
                        }
                }
       }
}</span>

       运行结果:

JavaSE入门学习51:多线程编程(二)_第5张图片

        (5)线程的优先级别

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

度哪个线程来执行。

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

       Thread.MIN_PRIORITY=1

       Thread.MAX_PRIORITY=10

       Thread.NORM_PRIORITY=5

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

       获得线程对象的优先级的方法:

       int getPriority();

       设置线程对象的优先级的方法:

       void setPriority(int newPriority);

       实例1代码:

<span style="font-size:18px;">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("线程1: " + i);
		}
	}
}

class T2 implements Runnable {
	public void run() {
		for(int i=0; i<100; i++) {
			System.out.println("线程2: " + i);
		}
	}
}</span>

       运行结果:


        线程1的优先级高于线程2,因此线程1获得CPU的时间片多于线程2的时间片。

        实例2代码:

<span style="font-size:18px;">public class TestThread6 {	
	public static void main(String args[]){
		Thread t = new Runner6();
   	        t.start();
		
		for(int i=0; i<10; i++) {
			System.out.println("MainThread主线程: " + i);
		}
        }
}

class Runner6 extends Thread {
	public void run() {
		System.out.println(Thread.currentThread().isAlive());
		for(int i=0;i<10;i++) {
			System.out.println("子线程 " + i);
		}
	}
}</span>

        运行结果:

JavaSE入门学习51:多线程编程(二)_第6张图片

        Thread.currentThread().isAlive()方法用于测试线程是否处于活动状态。

        三线程同步

        在Java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性,每个对象都对应于一个可称为互斥锁的

标记,这个标记保证在任一时刻,只能有一个线程访问的该对象。

        (1)synchronized关键字的用法

        关键字synchronized来与对象的互斥锁联系,当某个对象synchronized修饰时,表明该对象在任一时刻只能有一

个线程访问。

        synchronized关键字的使用方法:

<span style="font-size:18px;">synchronized(this){
		num ++;
	        try{
		        hread.sleep(1);
		}catch(InterruptedException e) {}
	        System.out.println(name+", 你是第"+num+"个使用timer的线程");
}</span>

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

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

        实例代码:

<span style="font-size:18px;">public class TestSync implements Runnable {
	Timer timer = new Timer();
	
	public void run(){
		timer.add(Thread.currentThread().getName());
    }
	
    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();
    }
}

class Timer{
    private static int num = 0;

    public void add(String name){
	    num ++;
	    try {Thread.sleep(1);} 
	    catch (InterruptedException e) {}
	    System.out.println(name+", 你是第"+num+"个使用timer的线程");
    }
}</span>

        运行结果:

JavaSE入门学习51:多线程编程(二)_第7张图片
       显然上述的结果令我们不满意,这就需要使用线程同步机制。     

       改写后的使用同步锁块的代码:

<span style="font-size:18px;">public class TestSync implements Runnable {
	Timer timer = new Timer();
	
	public void run(){
		timer.add(Thread.currentThread().getName());
    }
	
    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();
    }
}


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

       运行结果:

JavaSE入门学习51:多线程编程(二)_第8张图片
       改写后的使用同步锁的代码:

<span style="font-size:18px;">public class TestSync implements Runnable {
	Timer timer = new Timer();
	
	public void run(){
		timer.add(Thread.currentThread().getName());
        }
	
       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();
       }
}

class Timer{
	private static int num = 0;
	
        public synchronized void add(String name){
		num ++;
	        try{
			Thread.sleep(1);
		}catch(InterruptedException e) {}
	       System.out.println(name+", 你是第"+num+"个使用timer的线程");
    }
}</span>

       编译运行是和上述同样的结果。

       (2)死锁

       所谓死锁: 是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现

象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进

程称为死锁进程。

       死锁产生的实例代码:

<span style="font-size:18px;">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();
	}
}</span>

       运行结果:

JavaSE入门学习51:多线程编程(二)_第9张图片

       

你可能感兴趣的:(JavaSE,线程同步与互斥,多线程编程,Thread类,Runnable接口)