首页 >

详细了解java多线程机制

Java|java教程详细了解java多线程机制
java
Java-java教程
asp.net zero 源码,vscode pixhawk,ubuntu终端换行,tomcat 206,sqlite 转数字,香港免备案服务器,好看的树形菜单插件,前端框架编辑教程,网络爬虫 jar,php数组转,提升网站排名seo,房产网站php代码,圣诞节网页模板下载,帝国cms html5模板,js写登陆注册页面,会员积分管理系统源码,服务端程序连接数据库lzw
《java视频教学》
消消乐 源码,ubuntu断电后黑屏,山上爬虫的视频,php无缝,山西seo方案lzw
A、程序、进程、线程1.1 什么是程序
最小化qq源码,vscode监视变量不可用,ubuntu 挂载光盘,tomcat监控优化,sqlite内存表,网页设计 asp,手机怎么开虚拟服务器,单页滚动插件,前端框架an,番禺爬虫店,php项目开发教程,seo赚钱的套路,springboot 踢出用户,旅游商城网站模板免费下载,网页制作教程html,maccms8.x 模板,angular 后台管理系统,手机下载页面模板,全能企业网站管理系统,辅助程序lzw
详细了解java多线程机制

1.2 什么是进程

详细了解java多线程机制
目前操作系统都是支持多进程,可以同时执行多个进程,通过进程ID区分
详细了解java多线程机制

1.3 什么是线程

详细了解java多线程机制
详细了解java多线程机制
线程的组成

线程的特点

1.4 进程和线程的区别B、创建线程的三种方式2.1 继承Thread类重写run()方法

具体实现

继承类

public class MyThread extends Thread {    @Override    public void run() {        for (int i = 1; i " + i);        }    }}

测试类

public class TestThread {    public static void main(String[] args) {        MyThread myThread = new MyThread();        myThread.start();        for (int i = 1; i "+i);        }    }}

结果
详细了解java多线程机制

获取线程ID和名称

代码

public class TestThread {	public static void main(String[] args) {		MyThread t=new MyThread();		t.start();        //只能在继承Thread类的情况下用		System.out.println("线程id:"+t.getId());		System.out.println("线程名字:"+t.getName());        //调用Thread类的静态方法获取当前线程(这里获取的是主线程)		System.out.println("线程id:"+Thread.currentThread().getId());		System.out.println("线程名字:"+Thread.currentThread().getName());	}}

详细了解java多线程机制

修改线程名称

代码

public class MyThread extends Thread{	public MyThread() {}//无参构造器	public MyThread(String name) {		super(name);	}	public void run() {		for(int i=1;i<=50;i++) {}	}}
public class TestThread {	public static void main(String[] args) {		MyThread t1=new MyThread("子线程1");//通过构造方法		MyThread t2=new MyThread();		t2.setName("子线程2");		System.out.println("线程t1的id:"+t1.getId()+" 名称:"+t1.getName());		System.out.println("线程t2的id:"+t2.getId()+" 名称:"+t2.getName());	}}

详细了解java多线程机制

2.2 实现Runnable接口实现run()方法

具体实现

实现接口

public class MyRunnable implements Runnable{//实现接口	@Override	public void run() {//实现run方法		// TODO Auto-generated method stub		for(int i=1;i<=10;i++) {			System.out.println("子线程:"+i);		}	}}

测试类

public class TestRunnable {	public static void main(String[] args) {		//1.创建MyRunnable对象,表示线程执行的功能		Runnable runnable=new MyRunnable();		//2.创建线程对象		Thread th=new Thread(runnable);		//3.启动线程		th.start();		for(int i=1;i<=10;i++) {			System.out.println("主线程:"+i);		}			}}

详细了解java多线程机制

使用匿名内部类

public class TestRunnable {	public static void main(String[] args) {		Runnable runnable=new Runnable() {						@Override			public void run() {				// TODO Auto-generated method stub				for(int i=1;i<=10;i++) {					System.out.println("子线程:"+ i);				}			}		};				Thread th=new Thread(runnable);		th.start();	}}

2.3 实现Callable接口

Callable和Thread、Runnable比较

具体实现

实现接口

import java.util.Random;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;public class TestCallable implements Callable{	@Override	public Integer call() throws Exception {		// TODO Auto-generated method stub		return new Random().nextInt(10);	}}

测试类

import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;public class Test {	public static void main(String[] args) throws InterruptedException, ExecutionException {		TestCallable tc=new TestCallable();		FutureTask ft=new FutureTask(tc);		//创建线程对象		Thread th=new Thread(ft);		th.start();		//获取线程得到的返回值		Integer In=ft.get();		System.out.println(In);	}}

C、线程的状态3.1 基本四状态

详细了解java多线程机制

3.2 等待状态

详细了解java多线程机制

3.3 阻塞状态

详细了解java多线程机制

D、线程常用的方法4.1 线程休眠(sleep)

子线程

public class SleepThread extends Thread{    @Override    public void run() {        for (int i = 1; i <= 10; i++) {            System.out.println(Thread.currentThread().getName()+":"+i);            try {Thread.sleep(100);            } catch (InterruptedException e) {e.printStackTrace();            }        }    }}

PS:sleep()的异常在run方法中是不能抛出的,只能用try–catch处理
测试类

public class Test01 {    public static void main(String[] args) {        SleepThread sleepThread = new SleepThread();        sleepThread.start();    }}

结果:每次间隔100ms输出一次
详细了解java多线程机制

4.2 线程放弃(yield)

子线程

public class YieldThread extends Thread{    @Override    public void run() {        for (int i=1;i<=10;i++){            System.out.println(Thread.currentThread().getName()+":"+i);            Thread.yield();//主动放弃资源        }    }}

测试类

public class Test01 {    public static void main(String[] args) {        YieldThread yieldThread01 = new YieldThread();        YieldThread yieldThread02 = new YieldThread();        yieldThread01.start();        yieldThread02.start();    }}

结果:基本都会交替进行,也会有一个线程连输出
详细了解java多线程机制

4.3 线程加入(join)

子线程

public class JoinThread extends Thread{    @Override    public void run() {        for (int i=1;i<=10;i++){            System.out.println(Thread.currentThread().getName()+":"+i);        }    }}

测试类

public class Test01 {    public static void main(String[] args) throws InterruptedException {        for (int i=1;i<=10;i++){            System.out.println(Thread.currentThread().getName()+":"+i);            if(i==5){JoinThread joinThread = new JoinThread();joinThread.start();joinThread.join();            }        }    }}

结果:当主线程打印到5的时候,这时候子线程加入进来,就先执行完子线程,在执行主线程
详细了解java多线程机制

4.4 守护线程(setDaemon)

子线程

public class TestThread extends Thread{    @Override    public void run() {        for(int i=1;i<=1000;i++){            System.out.println(Thread.currentThread().getName()+":"+i);            try {Thread.sleep(50);            } catch (InterruptedException e) {e.printStackTrace();            }        }    }}

测试类

public class Test01 {    public static void main(String[] args) throws InterruptedException {        TestThread daemonThread = new TestThread();        daemonThread.setDaemon(true);//设置守护线程        daemonThread.start();        for (int i=1;i<=10;i++){            System.out.println(Thread.currentThread().getName()+":"+i);            Thread.sleep(100);        }    }}

结果:当主线程结束时,子线程也跟着结束,并不会继续执行下去打印输出
详细了解java多线程机制

4.5 线程优先级(setPriority)

子线程

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

测试

public class Test01 {    public static void main(String[] args) throws InterruptedException {        TestThread th1 = new TestThread();        TestThread th2 = new TestThread();        TestThread th3 = new TestThread();        th1.setPriority(10);//设置线程1优先级10        th1.start();        th2.start();//线程2优先级默认不变,为5        th3.setPriority(1);//设置线程3优先级为1        th3.start();    }}

结果:优先级(th1>th2>th3)线程3应该在最后打印
详细了解java多线程机制

E、线程安全问题5.1 卖票案例

需求:模拟三个窗口,每个窗口有100个人,同时抢10张票
详细了解java多线程机制
使用继承Runnable接口的方法

public class BuyTicketRunnable implements Runnable{		private int ticketNum=10;	@Override	public void run() {		for(int i=1;i<=100;i++) {			if(ticketNum<=0) break;			System.out.println("在"+Thread.currentThread().getName()+"买到了第"+ticketNum+"张票!");			ticketNum--;		}	}}

测试方法

public class BuyTicketTest {	public static void main(String[] args) {		// TODO Auto-generated method stub		Runnable runnable=new BuyTicketRunnable();				Thread th1=new Thread(runnable,"窗口1");		Thread th2=new Thread(runnable,"窗口2");		Thread th3=new Thread(runnable,"窗口3");				th1.start();		th2.start();		th3.start();	}}

结果
详细了解java多线程机制

5.2 同步代码块

对卖票案例改进

public class BuyTicketRunnable implements Runnable{	static Object obj=new Object();	private int ticketNum=10;	@Override	public void run() {		for(int i=1;i<100;i++) {            //把具有安全隐患的代码锁住即可,如果锁多了就会效率低 			synchronized (obj) {//锁必须多个线程用的是同一把锁!!也可以使用this,表示的是该对象本身				System.out.println("在"+Thread.currentThread().getName()+"买到了第"+ticketNum+"张票!");				ticketNum--;				}		}	}}

5.3 同步方法

买票案例改进

public class BuyTicketRunnable implements Runnable{	private int ticketNum=10;	@Override	public void run() {		for(int i=1;i0) {			System.out.println("在"+Thread.currentThread().getName()+"买到了第"+ticketNum+"张票!");			ticketNum--;			}	}}

5.4 Lock锁

对买票案例改进

import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class BuyTicketRunnable implements Runnable{	private int ticketNum=10;	Lock lock=new ReentrantLock();//接口=实现类  可以使用不同的实现类	@Override	public void run() {		for(int i=1;i0) {					System.out.println("在"+Thread.currentThread().getName()+"买到了第"+ticketNum+"张票!");					ticketNum--;					}			}catch(Exception e) {				e.printStackTrace();			}finally {				 //关闭锁:--->即使有异常,这个锁也可以得到释放				lock.unlock();			}		}	}}

5.5 线程死锁

*案例:男孩女孩一起去吃饭,但是桌子上只有两根筷子,如果两个人同时抢到一根筷子而不放弃,这样两个人都吃不上饭,这样就形成死锁了;必须要有一个人放弃争抢,等待另一个人用完,释放资源,这个人之后才会获得两根筷子,两个人才能都吃上饭 *

package 多线程;class Eat{    //代表两个筷子	public static Object o1=new Object();	public static Object o2=new Object();	public static void eat() {		System.out.println("可以吃饭了");	}}class BoyThread extends Thread{	public void run() {		synchronized (Eat.o1) {			System.out.println("男孩拿到了第一根筷子!");			synchronized (Eat.o2) {				System.out.println("男孩拿到了第二根筷子!");				Eat.eat();			}		}	}}class GirlThread extends Thread{	public void run() {		synchronized (Eat.o2) {			System.out.println("女孩拿到了第二根筷子!");			synchronized (Eat.o1) {				System.out.println("女孩拿到了第一根筷子!");				Eat.eat();			}		}	}}public class MyLock {	public static void main(String[] args) {		BoyThread boy=new BoyThread();		GirlThread girl=new GirlThread();		boy.start();		girl.start();	}}

结果
详细了解java多线程机制
解决办法

public class MyLock {	public static void main(String[] args) {		BoyThread boy=new BoyThread();		GirlThread girl=new GirlThread();		boy.start();		try {			Thread.sleep(100);		} catch (InterruptedException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		girl.start();	}}

详细了解java多线程机制
在写程序中要避免这种死锁:减少同步资源的定义,避免嵌套同步

F、线程通信问题6.1 wait()和wait(long timeout)

sleep和wait的区别:sleep进入阻塞状态没有释放锁,wait进入阻塞状态但是同时释放了锁

6.2 notify()和notifyAll()6.3 生产者和消费者问题

功能分解一:商品类

public class Product {//商品类    private String name;//名字    private String brand;//品牌    boolean flag = false;//设置标记,false表示商品没有,等待生产者生产    public synchronized void setProduct(String name, String brand) {//生产商品,同步方法,锁住的是this        if (flag == true) {//如果flag为true,代表有商品,不生产,等待消费者消费            try {wait();            } catch (InterruptedException e) {e.printStackTrace();            }        }        //生产商品        this.setName(name);        this.setBrand(brand);        System.out.println("生产者生产了" +this.getBrand() +this.getName());        //生产完,设置标志        flag = true;        //唤醒消费线程        notify();    }    public synchronized void getProduct() {        if (flag == false) {//如果是false,则没有商品,等待生产者生产            try {wait();            } catch (InterruptedException e) {e.printStackTrace();            }        }        //如果有商品,消费        System.out.println("消费者消费了" + this.getBrand() +this.getName());        //设置标志        flag = false;        //唤醒线程        notify();    }    public void setName(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void setBrand(String brand) {        this.brand = brand;    }    public String getBrand() {        return brand;    }}

功能分解二:生产者线程

public class ProducterThread extends Thread {//生产者线程    private Product p;    public ProducterThread(Product p) {        this.p = p;    }    @Override    public void run() {        for (int i = 1; i <= 10; i++) {            if(i%2==0){//如果是奇数,就生产巧克力,如果是偶数,就生产方便面p.setProduct("巧克力","德芙");            }else{p.setProduct("方便面","康师傅");            }        }    }}

功能分解三:消费者线程

public class CustomerThread extends Thread {//消费者线程    private Product pro;    public CustomerThread(Product pro) {        this.pro = pro;    }    @Override    public void run() {        for (int i = 1; i <= 10; i++) {            pro.getProduct();        }    }}

功能分解四:测试类

public class Test {    public static void main(String[] args) {        Product p = new Product();        ProducterThread pth = new ProducterThread(p);        CustomerThread cth = new CustomerThread(p);        pth.start();        cth.start();    }}

结果:生产者生产一件商品,消费者消费一件商品,交替进行

详细了解java多线程机制

《java视频教学》


  • 暂无相关文章
  • Posted in 未分类