多线程

  1. 定义
    进程:正在执行的应用程序
    线程:进程的执行单元,执行路径
    单线程:一个应用程序只有一条执行路径
    多线程:一个应用程序有多条执行路径
    多进程的意义? 提高CPU的使用率
    多线程的意义? 提高应用程序的使用率
  2. Java程序的运行原理及JVM的启动是多线程的吗?
    A:Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程。
    B:JVM的启动是多线程的,因为它最低有两个线程启动了,主线程和垃圾回收线程。
  3. 多线程的实现方案
    3.1继承Thread类
/* 方式1:继承Thread类。
 * 步骤
 * 		A:自定义类MyThread继承Thread类。
 * 		B:MyThread类里面重写run()?
 * 			为什么是run()方法呢?
 * 		C:创建对象
 * 		D:启动线程
 */

public class MyThreadDemo {
    public static void main(String[] args) {
        // 创建两个线程对象
        MyThread my1=new MyThread();
        MyThread my2=new MyThread();

        my1.start();
        my2.start();
    }

}
public class MyThread extends Thread{


    @Override
    public void run() {
        // 自己写代码
        for (int x = 0; x < 200; x++) {
            System.out.println(x);
        }
    }
}

3.2 实现Runnable接口

/*
 * 方式2:实现Runnable接口
 * 步骤:
 * 		A:自定义类MyRunnable实现Runnable接口
 * 		B:重写run()方法
 * 		C:创建MyRunnable类的对象
 * 		D:创建Thread类的对象,并把C步骤的对象作为构造参数传递
 */
public class MyRunnableDemo {
	public static void main(String[] args) {
		// 创建MyRunnable类的对象
		MyRunnable my = new MyRunnable();

		// 创建Thread类的对象,并把C步骤的对象作为构造参数传递
		// Thread(Runnable target)
		// Thread t1 = new Thread(my);
		// Thread t2 = new Thread(my);
		// t1.setName("林青霞");
		// t2.setName("刘意");

		// Thread(Runnable target, String name)
		Thread t1 = new Thread(my, "林青霞");
		Thread t2 = new Thread(my, "刘意");

		t1.start();
		t2.start();
	}
}
public class MyRunnable implements Runnable {

	@Override
	public void run() {
		for (int x = 0; x < 100; x++) {
			// 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用
			System.out.println(Thread.currentThread().getName() + ":" + x);
		}
	}

}

多线程

  • 线程的生命周期
    多线程
    多线程

  • 线程安全问题引例

public class SellTicket implements Runnable {
	// 定义100张票
	private int tickets = 100;
	
	@Override
	public void run() {
		while (true) {
			// t1,t2,t3三个线程
			// 这一次的tickets = 1;
			if (tickets > 0) {
				// 为了模拟更真实的场景,我们稍作休息
				try {
					Thread.sleep(100); //t1进来了并休息,t2进来了并休息,t3进来了并休息,
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				System.out.println(Thread.currentThread().getName() + "正在出售第"
						+ (tickets--) + "张票");
				//窗口1正在出售第1张票,tickets=0
				//窗口2正在出售第0张票,tickets=-1
				//窗口3正在出售第-1张票,tickets=-2
			}
		}
	}
}
/*
 * 实现Runnable接口的方式实现
 * 
 * 通过加入延迟后,就产生了连个问题:
 * A:相同的票卖了多次
 * 		CPU的一次操作必须是原子性的
 * B:出现了负数票
 * 		随机性和延迟导致的
 */
public class SellTicketDemo {
	public static void main(String[] args) {
		// 创建资源对象
		SellTicket st = new SellTicket();

		// 创建三个线程对象
		Thread t1 = new Thread(st, "窗口1");
		Thread t2 = new Thread(st, "窗口2");
		Thread t3 = new Thread(st, "窗口3");

		// 启动线程
		t1.start();
		t2.start();
		t3.start();
	}
}
     上述安全问题出现原因是因为多个线程随机抢占一个执行权,且执行时候存在进程共享资源!且一个线程代码还没执行完毕,另一个进程会跑过来继续执行,那么共享资源这时候可能还是第一个线程状态,来不及发生变化,索引可能会出现两个线程执行结果相同;或者借着上一个线程继续执行,这时候程序来不及结束。
 那么解决上述问题就想办法让多个线程单独来执行代码,而不是随机执行这样会乱套!
  • 多线程安全问题原因:(作为今后判断程序是否会出现安全问题的依据)
    A:是否有多线程环境
    B:是否有共享数据
    C:是否有多条语句操作共享数据

多线程安全问题解决方案(三种方式)
A:同步代码块

synchronized(对象) {
				需要被同步的代码;
			}
			
			这里的锁对象可以是任意对象。
/*注意:
 * 			同步可以解决安全问题的根本原因就在那个对象上。该对象如同锁的功能。
 * 			多个线程必须是同一把锁。*/

public class SellTicket implements Runnable {
	// 定义100张票
	private int tickets = 100;
	//创建锁对象
	private Object obj = new Object();         //这里的对象必须是同一个对象。
@Override
	public void run() {
		while (true) {
			synchronized (obj) {
				if (tickets > 0) {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()
							+ "正在出售第" + (tickets--) + "张票");
				}
			}
		}
	}
}

public class SellTicketDemo {
	public static void main(String[] args) {
		// 创建资源对象
		SellTicket st = new SellTicket();

		// 创建三个线程对象
		Thread t1 = new Thread(st, "窗口1");
		Thread t2 = new Thread(st, "窗口2");
		Thread t3 = new Thread(st, "窗口3");

		// 启动线程
		t1.start();
		t2.start();
		t3.start();
	}
}

B:同步方法:把同步加在方法上,这里的锁对象是this关键字
C:静态同步方法:把同步加在方法上。

  • 线程安全类:StringBuffer Vector Hashtable 这些类里面都有Synchronized关键字保证代码同步!

锁问题

上一篇:Windows利用互斥对象实现线程同步---买火车票的案例


下一篇:【线段树】poj 2828 Buy Tickets