JAVAEE多线程技术
1 进程和线程的区别?
每一个计算机应用至少有一个进程,并对应一个进程号。
线程是比进程更加细粒度,一个进程可以有多个线程。可以并发执行多个任务。
并行和并发的区别:
并行:多个CPU实例或者多个机器同时执行一段处理逻辑。真正的同时。
并发:通过CPU调度算法,让用户看上去同时执行一段处理逻辑,并不是真正的同时。
2 java的多线程?thread
2.1 检测主机是否在线的单线程实现的案例。
public class PingHost {
public boolean checkHost(String ip) throws IOException { Process pro = Runtime.getRuntime().exec("ping "+ip); //判断返回信息是否包含TTL关键字 String line; BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream())); while((line=buf.readLine())!=null){ if(line.contains("TTL")){ System.out.println("主机"+ip+"可到达"); return true; }
} System.out.println("主机"+ip+"不可到达"); return false; } /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { PingHost ph = new PingHost(); for (int i = 1; i < 50; i++) { ph.checkHost("172.16.22."+i); } } |
单线程缺点很明显:所有的操作顺序,时间长,效率极低。
2.2 多线程实现检测主机在线
package com.aaa.thread; import java.io.IOException;/** * @author sunshaoshan * @description 通过继承thread父类实现多线程 * @company AAA软件 * 2017-12-19下午2:40:07 */ public class MultiThreadByThread extends Thread { private String ip; public MultiThreadByThread(String ip) { super(); this.ip = ip; } @Override public void run() { try { PingHost.checkHost(ip); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }} |
package com.aaa.thread; import java.io.IOException; /** * @author sunshaosahn * @description 通过实现Runnable接口实现多线程 * @company AAA软件 * 2017-12-19下午2:45:44 */ public class MultiThreadByRunnable implements Runnable { private String ip;
public MultiThreadByRunnable(String ip) { super(); this.ip = ip; } @Override public void run() { try { PingHost.checkHost(ip); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
测试的时候不一样
//测试thread方式 /* for (int i = 1; i < 50; i++) { MultiThreadByThread btt =new MultiThreadByThread("172.16.22."+i); btt.start(); }*/ //测试runnable方式 for (int i = 1; i < 50; i++) { MultiThreadByRunnable mtb =new MultiThreadByRunnable("172.16.22."+i); new Thread(mtb).start(); } |
3 thread和runnable的区别?
类与接口的区别?类单继承,接口多实现。
出售火车票?
3.1 如果使用thread方式,火车票资源不共享,各卖各。
package com.aaa.thread; /** * @author sunshaoshan * @description 多线程出售火车票 * @company AAA软件 * 2017-12-19下午2:54:04 */ public class ThreadTicket extends Thread { private int ticketnum=5; private String name; public ThreadTicket(String name) { super(); this.name = name; };
@Override public void run() { for (int i = 1; i <=5; i++) { System.out.println(name+"卖票"+ticketnum--); } }
} |
3.2 使用runnable方式,可以实现资源共享,但是出现重复卖的情况。
package com.aaa.thread; /** * @author sunshaoshan * @description 多线程出售火车票 * @company AAA软件 * 2017-12-19下午2:54:04 */ public class RunnableTicket implements Runnable { private int ticketnum=5;
@Override public void run() {
for (int i = 1; i <=5; i++) { //Thread.currentThread().getName()获取当前进程名称 if(ticketnum>0){
System.out.println(Thread.currentThread().getName()+"卖票"+ticketnum--); } } }
} 售票员赵敏卖票5 售票员小昭卖票5 售票员赵敏卖票4 售票员小昭卖票3 售票员赵敏卖票2 售票员小昭卖票1 |
3.3 解决方式,使用synchronized关键字
package com.aaa.thread; /** * @author sunshaoshan * @description 多线程出售火车票 * @company AAA软件 * 2017-12-19下午2:54:04 */ public class RunnableTicket implements Runnable { private int ticketnum=15;
@Override public void run() {
for (int i = 1; i <=15; i++) { synchronized (this) { //Thread.currentThread().getName()获取当前进程名称 if(ticketnum>0){ try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"卖票"+ticketnum--); } } } }
} |
4 线程的各种状态
当代码段被synchronized包含时,必须要等到代码段执行完之后才开始下一线程。
package com.aaa.thread; public class LockTest { /** * @param args */ public static void main(String[] args) { final Object lock = new Object(); //创建两个线程 Runnable t1= new Runnable() {
@Override public void run() { synchronized (lock) { System.out.println(1); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(2); }
} }; Runnable t2= new Runnable() {
@Override public void run() { synchronized (lock) { System.out.println(3); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(4); }
} };
new Thread(t1).start(); new Thread(t2).start(); } } |
sleep和wait的区别
1,sleep是thread类的方法,wait是object的方法。
2,wait不会自己醒,sleep睡完能够自己唤醒,sleep必须指定睡眠时间。
3,线程执行到sleep不会释放锁,但是wait会释放锁。
package com.aaa.thread; public class LockTest { /** * @param args */ public static void main(String[] args) { final Object lock = new Object(); //创建两个线程 Runnable t1= new Runnable() {
@Override public void run() { synchronized (lock) { System.out.println(1); try { lock.wait();//一旦线程通过wait进入等待,不会自己醒 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(2); }
} }; Runnable t2= new Runnable() {
@Override public void run() { synchronized (lock) { System.out.println(3); try { Thread.sleep(3000); lock.notify();//唤醒lock } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(4); }
} };
new Thread(t1).start(); new Thread(t2).start(); } } |
5 线程死锁
package com.aaa.thread; public class DeadLockTest implements Runnable { private static Father father = new Father(); private static Child child = new Child(); private boolean flag = false; @Override public void run() { if(flag){ //父亲 synchronized (father) {
father.say(); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (child) { father.get(); } } }else { //孩子 synchronized (child) {
child.say(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (father) { child.get(); }
} }
}
public static void main(String[] args) { DeadLockTest d1= new DeadLockTest(); DeadLockTest d2= new DeadLockTest(); d1.flag=true; d2.flag=false; new Thread(d1).start(); new Thread(d2).start(); } } |
- 点赞
- 收藏
- 关注作者
评论(0)