package module;
public class ClassRoom1 {
public static void main(String[] args) {
MYthread my = new MYthread();
Thread t1 = new Thread(my,"窗口1-");
Thread t2 = new Thread(my,"窗口2-");
Thread t3 = new Thread(my,"窗口3-");
t1.start();
t2.start();
t3.start();
}
}
并行:指的是多个任务在多个CPU上执行
并发:指的是多个任务在CPU上交通执行
进程与线程:
进程:进程就是操作系统正在运行的程序,所以进程也就是正在运行的程序
线程:是程序运行的基本单元,当系统操作一个一个程序的时候会建立一个进程,该进程必须建立一个线程,这个线程被称为主线程,在运行程序的过程中每一个程序至少有一个线程,
多线程:
指的是一个硬件或者软件在同一时间支持多条线程,,好处提升程序的效率
多线程的创建方式:
java.lang.Thread,是线程类,可以用来创建线程处理任务使用,两个比较重要的方法:
public void run():线程执行任务的方法:是线程启动后第一个执行的方法。
public void start() 启动线程的方法,线程对象调用之后会执行run方法。
线程类
package module;
public class ClassRoom1 {
public static void main(String[] args) {
MYthread my = new MYthread();
my.start();
for (int i = 0; i < 200; i++){
System.out.println("main方法开始执行了");
}
}
}
main方法
package module;
public class MYthread extends Thread{//继承线程类
@Override
public void run() {//重写thread里面的run方法
for (int i = 0; i < 200; i++) {
System.out.println("线程开始执行了");
}
}
}
创建方式二:
实现Runable接口;
线程类:
package module;
public class MYthread implements Runnable{//实现Runable接口
@Override
public void run() {//重写thread里面的run方法
for (int i = 0; i < 200; i++) {
System.out.println("线程开始执行了");
}
}
}
package module;
public class ClassRoom1 {
public static void main(String[] args) {
MYthread my = new MYthread();//创建线程任务对象
Thread t1 = new Thread(my);//创建线程对象
t1.start();//开启线程
for (int i = 0; i < 200; i++){
System.out.println("main方法开始执行了");
}
}
}
运行结果:
实现与继承的优缺点:
继承:优点:编程简单可以直接使用Thread类的方法
缺点:只能单继承,扩展性差
实现:优点:可以多实现,扩展性大
缺点:代码繁琐不能直接使用Thread类里面的方法。
Thread常用方法
String getName():给线程取名字。
void setName(String name),通过构造方法给线程取名字,
public void Thread currenThread():获取当前线程对象:
public static void sleep(long time):指定线程休眠时间。
package module;
public class MYthread implements Runnable{//实现Runable接口
@Override
public void run() {//重写thread里面的run方法
for (int i = 0; i < 200; i++) {
String name = Thread.currentThread().getName();//获取线程名称
System.out.println(name+i);
}
}
}
package module;
public class ClassRoom1 {
public static void main(String[] args) {
MYthread my = new MYthread();//创建线程任务对象
Thread t1 = new Thread(my,"新线程");//指定执行任务的线程
t1.start();//开启线程
try {
Thread.sleep(100);//指定线程休眠的时间
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for (int i = 0; i < 200; i++){
//获取main方法里面线程的名称
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
线程安全问题:
线程类:
package module;
public class MYthread implements Runnable{
private int ticket=100;
@Override
public void run() {
while(true){
if(ticket>0){
String name = Thread.currentThread().getName();
System.out.println(name+"正在买第:"+ticket+"张票");
ticket--;
}
}
}
}
package module;
public class ClassRoom1 {
public static void main(String[] args) {
MYthread my = new MYthread();
Thread t1 = new Thread(my,"窗口1-");
Thread t2 = new Thread(my,"窗口2-");
Thread t3 = new Thread(my,"窗口3-");
t1.start();
t2.start();
t3.start();
}
}
可以看到运行的时候出现多次重复的票数;解决:
同步代码块:
package module;
public class MYthread implements Runnable {
private int ticket = 100;
private Object lock = new Object();
@Override
public void run() {
for (int i = 1; i <= ticket; i++) {
synchronized (lock) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (ticket > 0) {
String name = Thread.currentThread().getName();
System.out.println(name + "正在买第:" + ticket + "张票");
ticket--;
}
}
}
}
}
添加同步代码块之后在去运行main方法就不会出现卖一样的票数了
同步方法:
package module;
public class MYthread implements Runnable {
private int ticket = 100;
@Override
public void run() {
while (true) {
mathod();
}
}
public synchronized void mathod() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (ticket > 0) {
String name = Thread.currentThread().getName();
System.out.println(name + "正在买第:" + ticket + "张票");
ticket--;
}
}
}
Lock锁机制:
package module;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MYthread implements Runnable {
private int ticket = 100;
Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
lock.lock();
if (ticket <=0) {
break;
}
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
String name = Thread.currentThread().getName();
System.out.println(name + "正在买第:" + ticket + "张票");
ticket--;
}
lock.unlock();
}
}
}
运行main方法都没有重票的以上几种方法是解决重票的问题。