1.什么是线程和进程?两者之间的关系?
进程是程序的一次动态执行过程,线程和进程都是实现并发的基本单位。
线程是比进程更小的执行单位,一个线程可以由多个线程组成,线程消亡了,进程还在,但进程消亡了,线程一定也随之消亡。
2.线程的创建有两种方法:继承Thread类和实现Runnable接口,其中继承Thread类受java单继承局限,实现Runnable接口更具灵活性,有利于功能扩展性和线程间的数据共享,如:Student类可以继承Person类同时实现Runnable。
3.线程运行的五种状态
a.创建--继承Thread类和实现Runnable接口
b.就绪状态--调用start()方法后,线程有了执行的资格,等待获取cpu使用权
c.运行状态--线程有执行的资格且获得了cpu使用权
d.阻塞状态--I/O操作 wait() sleep()等导致阻塞,当阻塞条件解除重新回到就绪状态进行排队获取cpu执行权
e.死亡状态--stop()或者线程执行完毕
4.线程名字的设置、获取 setName getName()
静态方法Thread.currentThread()获取正在运行的线程
5.线程安全之(同步代码块和同步方法)
6. 使用同步方法完成卖票程序
7.同步方法用static修饰后,用的锁不是this静态方法也不可以定义this,静态方法进入内存后,没有本类对象,而是有本类的的字节码对象所以静态同步方法锁的对象是 类名.class
8.单例模式之同步
9.死锁
进程是程序的一次动态执行过程,线程和进程都是实现并发的基本单位。
线程是比进程更小的执行单位,一个线程可以由多个线程组成,线程消亡了,进程还在,但进程消亡了,线程一定也随之消亡。
2.线程的创建有两种方法:继承Thread类和实现Runnable接口,其中继承Thread类受java单继承局限,实现Runnable接口更具灵活性,有利于功能扩展性和线程间的数据共享,如:Student类可以继承Person类同时实现Runnable。
public class ThreadStartDemo1 { public static void main(String[] args) { MyThread my1=new MyThread("one"); MyThread my2=new MyThread("two"); my2.setName("TWO+++"); my1.start(); my2.start(); for(int i=0;i<30;i++) { System.out.println("main----"+i); } } } class MyThread extends Thread { //private String name; public MyThread(String name) { super(name); } public void run() { for(int i=0;i<30;i++) { System.out.println(Thread.currentThread().getName()+"----"+i); } } }
3.线程运行的五种状态
a.创建--继承Thread类和实现Runnable接口
b.就绪状态--调用start()方法后,线程有了执行的资格,等待获取cpu使用权
c.运行状态--线程有执行的资格且获得了cpu使用权
d.阻塞状态--I/O操作 wait() sleep()等导致阻塞,当阻塞条件解除重新回到就绪状态进行排队获取cpu执行权
e.死亡状态--stop()或者线程执行完毕
4.线程名字的设置、获取 setName getName()
静态方法Thread.currentThread()获取正在运行的线程
5.线程安全之(同步代码块和同步方法)
/*银行一个小金库,由两个客户分别存3次钱,每次存100元,统计每次客户存钱后金库总额*/ public class BankDemo { public static void main(String[] args) { Cus c=new Cus(); Thread t1=new Thread(c); Thread t2=new Thread(c); t1.start(); t2.start(); } } /* //使用同步代码块的方法保障线程安全 class Bank { private int sum=0; public void add(int n) { synchronized(this) { sum=sum+n; try { Thread.sleep(10); } catch (Exception e) { e.printStackTrace(); } System.out.println("sum="+sum); } } } */ //使用同步方法保障线程安全 class Bank { private int sum=0; public synchronized void add(int n) { sum=sum+n; try { Thread.sleep(10); } catch (Exception e) { e.printStackTrace(); } System.out.println("sum="+sum); } } class Cus implements Runnable { private Bank b=new Bank(); public void run() { for(int i=0;i<3;i++) { b.add(100); // 如果在此处进行同步的话,就是要等一个客户执行自己的全部操作次数才让另外一个客户进入操作,不符合实际 } } }
6. 使用同步方法完成卖票程序
public class TicketDemo { public static void main(String[] args) { MyThread my=new MyThread(); Thread t1=new Thread(my); Thread t2=new Thread(my); Thread t3=new Thread(my); Thread t4=new Thread(my); t1.start(); t2.start(); t3.start(); t4.start(); } } class MyThread implements Runnable { private /*static */ int tic=30; public void run() { for(int i=0;i<300;i++) { if(tic>0) { System.out.println("sale tickets:"+tic--); } } } }
7.同步方法用static修饰后,用的锁不是this静态方法也不可以定义this,静态方法进入内存后,没有本类对象,而是有本类的的字节码对象所以静态同步方法锁的对象是 类名.class
/* 同步函数用的是哪一个锁呢? 函数都要被对象调用,那么函数都有一个所属对象给引用,就是this 验证同步函数的锁就是this */ public class ThisLockDemo1 { public static void main(String[] args) { MyThread my=new MyThread(); Thread t1=new Thread(my); Thread t2=new Thread(my); t1.start(); try{Thread.sleep(100); }catch(Exception e){ e.printStackTrace();} my.flag=false; t2.start(); } } class MyThread implements Runnable { private int tic=30; boolean flag=true; public void run() { //Object obj=new Object(); if(flag) { while(true) { synchronized(this) //此处如果传入的参数是obj.那么输出数据将会错乱,因为多个线程间用的不是一个锁 { if(tic>0) { try{Thread.sleep(100); }catch(Exception e){} System.out.println(Thread.currentThread().getName()+" sale @@@@@@:"+tic--); } } } } else { while(true) { this.take(); } } } public synchronized void take() { if(tic>0) { try{Thread.sleep(200); } catch(Exception e){} System.out.println(Thread.currentThread().getName()+" take ######:"+tic--); } } }
public class ThisLockDemo2 { public static void main(String[] args) { MyThread my=new MyThread(); Thread t1=new Thread(my); Thread t2=new Thread(my); t1.start(); try{Thread.sleep(100); }catch(Exception e){ e.printStackTrace();} my.flag=false; t2.start(); } } class MyThread implements Runnable { private static int tic=30; boolean flag=true; public void run() { //Object obj=new Object(); if(flag) { while(true) { synchronized(MyThread.class) //此处如果传入的参数是obj.那么输出数据将会错乱,因为多个线程间用的不是一个锁 { if(tic>0) { try{Thread.sleep(100); }catch(Exception e){} System.out.println(Thread.currentThread().getName()+" sale @@@@@@:"+tic--); } } } } else { while(true) { take(); } } } public static synchronized void take()//同步方法用变为静态后,输出错误数据 { if(tic>0) { try{Thread.sleep(200); } catch(Exception e){} System.out.println(Thread.currentThread().getName()+" take ######:"+tic--); } } }
8.单例模式之同步
//单例模式 //饿汉式 class Singleton { private static final Singleton s=new Singleton(); private Singleton(){} //将构造方法私有化 public static Singleton getInstance() { return s; } } //懒汉式(延迟加载) class Singleton { private static Singleton s=null; private Singleton(){} //将构造方法私有化 public static Singleton getInstance() { if(s==null) { s=new Singleton(); return s; } } } //懒汉式(延迟加载) //被多线程访问时存在线程安全问题,所以可以采用同步方法 //保障线程安全,但这么做的缺点是,需要对锁反复进行判断, //比较低效 class Singleton { private static Singleton s=null; private Singleton(){} //将构造方法私有化 public synchronized static Singleton getInstance() { if(s==null) { s=new Singleton(); } return s; } } //双重判断 可以减少锁的判断 提高代码执行效率 class Singleton { private static Singleton s=null; private Singleton(){} //将构造方法私有化 public static Singleton getInstance() { if(s==null) { synchronized(Singleton.class) { if(s==null) { s=new Singleton(); } } } return s; } }
9.死锁
//1.死锁是程序都在等待对方先完成,在僵持不下的情况下,就会使程序的执行处于停滞状态 //2.同步的嵌套会产生死锁,过多的同步会产生死锁 public class DeadLock { public static void main(String[] args) { MyLock lock1=new MyLock(); MyLock lock2=new MyLock(); lock1.flag=true; lock2.flag=false; Thread t1=new Thread(lock1); Thread t2=new Thread(lock2); t1.start(); t2.start(); } } class ZhangSan { public void say() { System.out.println("张三说你把画给我!"); } public void get() { System.out.println("张三得到了画"); } } class LiSi { public void say() { System.out.println("李四说你把书给我!"); } public void get() { System.out.println("李四得到了书"); } } class MyLock implements Runnable { boolean flag; private static ZhangSan zs=new ZhangSan();//声明static类型对象,数据共享 private static LiSi ls=new LiSi();//static很重要 public void run() { if(flag) { zs.say(); synchronized(zs) { try{Thread.sleep(200);}catch(Exception e){} synchronized(ls) { zs.get(); } } }else { ls.say(); synchronized(ls) { try{Thread.sleep(200);}catch(Exception e){} synchronized(zs) { ls.get(); } } } } }
发表评论
-
多线程--join和yield
2011-10-02 09:08 825//A线程遇到B线程join A线程让出执行权 直到B线程执行 ... -
【多线程】线程的停止
2011-10-02 08:52 1125Thread类中stop方法停止线程存在安全隐患,怎么让一个线 ... -
JDK 5.0中的Lock实现线程同步
2011-10-02 08:44 1231JDK 5中将synchronized替换成现实的Lock,将 ... -
多线程--生产者消费者-
2011-10-02 04:53 718思考:1.为什么生产者和消费者中要使用while循环判断? 使 ... -
多线程
2011-10-02 04:13 844创建四个线程,两个线程运行加法运算,两个线程运行减法操作 pu ...
相关推荐
Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程...
vc++ 多线程教程---线程通信--利用事件对象,线程同步--使用信号量,线程同步--使用互斥量,线程同步--使用临界区
Java多线程--多线程相关概念
qt 多线程------- 串口通信 object 继承方式 配合我文章
人工智能-项目实践-多线程-多线程爬虫--抓取淘宝商品详情页URL 本项目是一个Java编写的多线程爬虫系统。此系统与我之前开发的ip-proxy-pools-regularly结合使用,共抓取了淘宝近3000个页面,从中解析到了近9万的...
Java多线程-Socket编程
多线程day2的资源
人工智能-项目实践-多线程-一个多线程多进程的下载DEMO 人工智能-项目实践-多线程-一个多线程多进程的下载DEMO
多线程day1的笔记
Java多线程--让主线程等待所有子线程执行完毕
人工智能-项目实践-多线程-tonado的multi-thread 多线程封装 Quick Start 1.在“biz”目录中创建一个py文件,文件名任意但最好不要跟第三方库冲突 2.使用 "Router.route" 装饰器注册函数到路由表中,仿造示例即可 ...
Posix多线程-共享内存
Java多线程--多线程知识点总结和企业真题
Java多线程--对比创建多线程的两种方式
人工智能-项目实践-多线程-多线程与高并发 多线程与高并发
Java多线程--线程间的通信
Java多线程--线程的生命周期
人工智能-项目实践-多线程-60行代码实现多线程PDF转Word 使用方法 clone或下载项目到本地 git clone git@github.com:simpleapples/pdf2word.git 进入项目目录,建立虚拟环境,并安装依赖 cd pdf2word python3 -m ...
人工智能-项目实践-多线程-Java多线程高并发实例 Java多线程高并发实例
Java多线程--线程安全问题练习题