Java多线程

线程就是程序执行的一条路径

创建线程两种方式对比:

  1. 继承Thread:可以直接使用Thread类中的方法,代码简单。但如果已经有了父类就不能使用这个方法(优先考虑)
  2. 实现Runnable接口:有了父类也没有关系,父类也可以实现接口,而且接口可以多实现。但需要先获得Thread对象后,才能获得Thread方法,代码复杂

两种方式源码对比:

  1. 继承Thread:由于子类重写了Thread类的run()方法,当调用start()方法,直接找子类的run()方法
  2. 实现Runnable接口:构造方法传入了Runnable的引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空编译时看的是Runnable的run(),运行时执行的是子类的run()方法。
package day23;

public class Dk1EstablishThread {

	//匿名内部类创建线程
	public static void main(String[] args) {
		//1.继承Thread
		new Thread() {
			public void run() {     //重写run()方法
				for (int i = 0; i < 10; i++) {
					System.out.println("继承Thread");
				}
			}
		}.start();;

		//2.实现Runnable接口
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					System.out.println("实现Runnable接口");
				}
				
			}
		}).start();
		//两个线程交替执行
	}

}

同步代码块:synchronized(锁){},任意对象都可以当作锁,匿名对象不行。

同步方法:

线程安全:Vector、StringBuffer、HashTable

线程不安全:ArrayList、StringBuilder、HashMap

Runtime类:

package day25;

public class Dk2Runtime {

	//Runtime单例设计模式
	public static void main(String[] args) {
		Runtime r = Runtime.getRuntime();
		//r.exec(dos命令);

	}
}

Timer类:

sleep()和wait()方法区别:

  1. sleep()方法必须传入参数,参数就是时间,当时间到了自动唤醒

    wait()方法不是必须传入参数,如果没有参数遇到wait()就等待,如果传入参数,等参数的时间到了后等待

  2. sleep()方法在同步中不释放锁,因为它可以自己醒来

    wait()方法在同步中释放锁,因为它需要别人叫醒

package day25;

public class Dk3Wait {

	//三个线程之间互相通信jdk1.5版本之前
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Printer p = new Printer();
		
		new Thread() {
			public void run() {
				while (true) {
					try {
						p.print1();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
		
		new Thread() {
			public void run() {
				while (true) {
					try {
						p.print2();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
		
		new Thread() {
			public void run() {
				while (true) {
					try {
						p.print3();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
	}

}

class Printer {
	private int flag = 1;            //定义标记
	private Object obj = new Object();
	public void print1() throws InterruptedException {
		synchronized (this) {
			while (flag != 1) {
				this.wait();
			}
			System.out.print("J");
			System.out.print("a");
			System.out.print("v");
			System.out.print("a");
			System.out.println();
			flag = 2;
			//this.notify();               //随机唤醒另一条线程
			this.notifyAll();              //唤醒所有线程
		}
	}
	
	public void print2() throws InterruptedException {
		synchronized (this) {
			while (flag != 2) {
				this.wait();
			}
			System.out.print("P");
			System.out.print("y");
			System.out.print("t");
			System.out.print("h");
			System.out.print("o");
			System.out.print("n");
			System.out.println();
			flag = 3;
			this.notifyAll();
		}
	}
	
	public void print3() throws InterruptedException {
		synchronized (this) {
			while (flag != 3) {
				this.wait();
			}
			System.out.print("C");
			System.out.print("+");
			System.out.print("+");
			System.out.println();
			flag = 1;
			this.notifyAll();
		}
	}
}
package day25;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Dk4Lock {

	//互斥锁
	public static void main(String[] args) {
		Printer2 p = new Printer2();
		
		new Thread() {
			public void run() {
				while (true) {
					try {
						p.print1();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
		
		new Thread() {
			public void run() {
				while (true) {
					try {
						p.print2();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
		
		new Thread() {
			public void run() {
				while (true) {
					try {
						p.print3();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
	

	}

}

class Printer2 {
	private ReentrantLock r = new ReentrantLock();
	private Condition c1 = r.newCondition();
	private Condition c2 = r.newCondition();
	private Condition c3 = r.newCondition();
	private int flag = 1;            //定义标记
	private Object obj = new Object();
	public void print1() throws InterruptedException {
		r.lock();
			if (flag != 1) {
				c1.await();        //也可以调用wait()
			}
			System.out.print("J");
			System.out.print("a");
			System.out.print("v");
			System.out.print("a");
			System.out.println();
			flag = 2;
			c2.signal();
		r.unlock();
	}
	
	public void print2() throws InterruptedException {
		r.lock();
			if (flag != 2) {
				c2.await();
			}
			System.out.print("P");
			System.out.print("y");
			System.out.print("t");
			System.out.print("h");
			System.out.print("o");
			System.out.print("n");
			System.out.println();
			flag = 3;
			c3.signal();
		r.unlock();
	}
	
	public void print3() throws InterruptedException {
		r.lock();
			if (flag != 3) {
				c3.await();
			}
			System.out.print("C");
			System.out.print("+");
			System.out.print("+");
			System.out.println();
			flag = 1;
			c1.signal();
		r.unlock();
	}
}

线程组:如果没有给定线程属于哪个组,默认就属于主线程组

package day25;

public class MyRunner implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + "..." + i);
		}
		
	}

}
package day25;

public class Dk5ThreadGroup {

	//线程组
	public static void main(String[] args) {
		MyRunner mr = new MyRunner();

		ThreadGroup tg = new ThreadGroup("我是一个线程组");
		Thread t1 = new Thread(tg,mr,"张三");            //将线程“张三”加入指定组
		Thread t2 = new Thread(tg,mr,"李四");
		System.out.println(tg.getName());
	}

}
//输出
我是一个线程组

线程池:程序启动一个新线程成本较高,使用线程池可以提高性能,尤其程序中创建大量生存期很短的线程时。线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。

从jdk1.5开始内置线程池

package day25;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Dk6ThreadPool {

	//线程池
	public static void main(String[] args) {
		ExecutorService pool = Executors.newFixedThreadPool(2);   //创建线程池,可以放两条线程
		MyRunner mr1 = new MyRunner();        //创建Runnable的子类对象
		MyRunner mr2 = new MyRunner();

		pool.submit(mr1);
		pool.submit(mr2);
		
		pool.shutdown();                          //关闭线程池,不接受新任务
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值