JAVA线程总结(三)

上边博客写到单例设计模式,回顾一下,单例设计模式是不允许别的类创建对象,只允许自己创建对象,别的类想访问只能通过类名.调用, 这次举一个例子,JAVA中有一个类Runtime,这个类便是应用了单例设计模式。

代码走起

Demo5_Runtime.java

package com.tao.thread;

import java.io.IOException;

/**
 * 多线程(Runtime类)
 * @author 天外飞星
	
 *
 */
public class Demo5_Runtime {
/**
 * 
 * @param args
 * @throws IOException 
 */
	public static void main(String[] args) throws IOException {
		Runtime runtime=Runtime.getRuntime();
	//	runtime.exec("shutdown -s -t 300"); //设置5分钟后关机
		runtime.exec("shutdown -a"); //设置取消上次的关机设置

	}

}

下面讲一个定时器的例子,每隔3s喊我起床背单词

Demo6_Timer.java

package com.tao.thread;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 定时器
 * @author 天外飞星
 *
 */
public class Demo6_Timer {
	public static void main(String[] args) throws InterruptedException {
		Timer t=new Timer();
		//三个参数,t.schedule(TimerTask的子类对象(指明任务),触发时间,多久执行一次)
		//注:118是2018-1900得到的,,必须减去1900
		t.schedule(new MyTimerTask(), new Date(118, 10, 18, 20, 40,30), 3000);
		while(true){
			Thread.sleep(1000);
			System.out.println(new Date());
		}
	}
	
}
class MyTimerTask extends TimerTask{
	public void run(){
		System.out.println("起床背英语单词儿...");
	}
}

两个线程间的通信

要求打印机执行完1后,马上把执行权给2,2执行完后立马把执行权给1,交替执行

实现一:

Demo1_Notify.java

package com.tao.thread2;

/**
 * 交替执行
 * 多线程(两个线程间的通信)
 * @author 天外飞星
 * 
 * 
 */
public class Demo1_Notify {
	public static void main(String[] args) {
		final Printer p = new Printer();
		new Thread() {
			public void run() {
				while (true) {
					try {
						p.print1();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}
		}.start();
		new Thread() {
			public void run() {
				while (true) {
					try {
						p.print2();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
	}
}

class Printer {
	private int flag = 1;
	public void print1() throws InterruptedException {
		synchronized (this) { // 同步代码块,锁机制,锁对象可以是任意的
			if(flag!=1){
				this.wait();    //当前线程等待
			}
			System.out.print("清");
			System.out.print("华");
			System.out.print("大");
			System.out.print("学");
			System.out.println();
			flag=2;
			this.notify();      //随机唤醒单个等待的进程
		}
	}

	public void print2() throws InterruptedException {
		synchronized (this) { // synchronized (new Demo())不可行,因为不是同一对象了
			if(flag!=2){
				this.wait();
			}
			System.out.print("我");
			System.out.print("爱");
			System.out.print("你");
			System.out.println();
			flag=1;
			this.notify();
		}

	}
}

三个或三个以上间的线程通信

三个线程交替执行

Demo2_NotifyAll.java

package com.tao.thread2;
/**
 * 多线程(三个或三个以上间的线程通信)
 * @author 天外飞星

 *
 */
public class Demo2_NotifyAll {
	
	public static void main(String[] args) {
		final Printer2 p1 = new Printer2();
		new Thread() {
			public void run() {
				while (true) {
					try {
						p1.print1();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}
		}.start();
		new Thread() {
			public void run() {
				while (true) {
					try {
						p1.print2();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}
		}.start();
		new Thread() {
			public void run() {
				while (true) {
					try {
						p1.print3();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}
		}.start();
	}
}
class Printer2 {
	private int flag = 1;
	public void print1() throws InterruptedException {
		synchronized (this) { // 同步代码块,锁机制,锁对象可以是任意的
			if(flag!=1){
				this.wait();    //当前线程等待
			}
			System.out.print("清");
			System.out.print("华");
			System.out.print("大");
			System.out.print("学");
			System.out.println();
			flag=2;
		//	this.notify();      //随机唤醒单个等待的进程
			this.notifyAll();  //唤醒所有进程,防止死锁
		}
	}

	public void print2() throws InterruptedException {
		synchronized (this) { // synchronized (new Demo())不可行,因为不是同一对象了
			if(flag!=2){
				this.wait();
			}
			System.out.print("我");
			System.out.print("爱");
			System.out.print("你");
			System.out.println();
			flag=3;
		//	this.notify();
			this.notifyAll();
		}

	}
	public void print3() throws InterruptedException {
		synchronized (this) { // synchronized (new Demo())不可行,因为不是同一对象了
			if(flag!=3){
				this.wait();
			}
			System.out.print("I");
			System.out.print("LOVE");
			System.out.print("YOU");
			System.out.println();
			flag=1;
		//	this.notify();
			this.notifyAll();
		}

	}
}

在这里插入图片描述

注意:三个以上线程通信要使用this.notifyAll(); 唤醒所有进程,防止死锁

三个或三个以上间的线程通信

实现二:

Demo3_ReentrantLock.java

package com.tao.thread2;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 多线程(三个或三个以上间的线程通信)
 * 多线程(JDK1.5的新特性互斥锁)
 * @author 天外飞星
 *
 */
public class Demo3_ReentrantLock {
	public static void main(String[] args) {
			final Printer3 p1 = new Printer3();
			new Thread() {
				public void run() {
					while (true) {
						try {
							p1.print1();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}

				}
			}.start();
			new Thread() {
				public void run() {
					while (true) {
						try {
							p1.print2();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}

				}
			}.start();
			new Thread() {
				public void run() {
					while (true) {
						try {
							p1.print3();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}

				}
			}.start();
	}
}
class Printer3 {
	private int flag = 1;
	private ReentrantLock r=new ReentrantLock(); //互斥锁
	private Condition c1=r.newCondition();   //信号量        
	private Condition c2=r.newCondition();   //信号量     
	private Condition c3=r.newCondition();   //信号量     
	public void print1() throws InterruptedException {
			r.lock();  //上锁
			if(flag!=1){
				c1.await();    //当前线程等待
			}
			System.out.print("清");
			System.out.print("华");
			System.out.print("大");
			System.out.print("学");
			System.out.println();
			flag=2;
		//	this.notify();      //随机唤醒单个等待的进程
			c2.signal();
			r.unlock();  //解锁
	}

	public void print2() throws InterruptedException {
			r.lock();  //上锁
			if(flag!=2){
				c2.await();
			}
			System.out.print("我");
			System.out.print("爱");
			System.out.print("你");
			System.out.println();
			flag=3;
		//	this.notify();
			c3.signal();
			r.unlock();  //解锁

	}
	public void print3() throws InterruptedException {
			r.lock();  //上锁
			if(flag!=3){
				c3.await();
			}
			System.out.print("I");
			System.out.print("LOVE");
			System.out.print("YOU");
			System.out.println();
			flag=1;	
		//	this.notify();
			c1.signal();
			r.unlock();  //解锁

	}
}

为了对线程的统一管理,引入了组的概念,比如要对许多线程做同类操作,把这些线程加入到一个组内,,然后让改组实行操作即可。

Demo4_ThreadGroup.java

package com.tao.thread2;
/**
 * 把t1,t2添加到一个线程组里
 * @author 天外飞星

 *
 */
public class Demo4_ThreadGroup {
	public static void main(String[] args) {
		MyRunable mr=new MyRunable();
		ThreadGroup tg=new ThreadGroup("我是一个新的线程组");
		Thread t1=new Thread(tg, mr);//把mr(未设置名称)线程添加到tg组
		Thread t2=new Thread(tg, mr, "李四");//把叫李四的线程添加到tg组
		System.out.println(t1.getName());
		System.out.println(t2.getName());
		System.out.println(t1.getThreadGroup().getName());
		System.out.println(t2.getThreadGroup().getName());
		//组方便对线程的同类操作
	}
}
class MyRunable implements Runnable{
	public void run(){
		for(int i=1;i<10;i++){
		System.out.println(Thread.currentThread().getName()+"...."+i);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42429369/article/details/84260443