博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA入门到精通-第40讲-线程
阅读量:6080 次
发布时间:2019-06-20

本文共 5213 字,大约阅读时间需要 17 分钟。

1167156-20181130180455948-710043225.png
 把思想转换成程序。
 
1167156-20181130180456337-403158296.png
 线程对象只能启动一个线程;
 导入导出项目:
1,copy
 
1167156-20181130180456677-1001046291.png
2,装到磁盘
3,导入:import---General---Existing Project into Workspace
1167156-20181130180457039-2022551607.png
 4,浏览Brose-Copy project into workspace
  把项目拷贝到Eclipse中,
  不选的话,直接操作;
-----------------------------------------
1167156-20181130180457389-1785463288.png
 这是可以的;
 
1167156-20181130180457625-1999404090.png
 这会报错,一个线程类只会启动一次;
 
1167156-20181130180457928-1528444625.png
  数据的并发;
 //售票窗口类
 
1167156-20181130180458251-241783467.png
//定义三个售票窗口
  
1167156-20181130180458535-999016508.png
 //控制出票速度:
 Thread.sleep(100);
 
1167156-20181130180458822-1853665608.png
 各卖各的票没有共享;
//看哪个线程在卖票
  
1167156-20181130180459110-164134934.png
 Thread.currentThread().getName() 
得到当前线程的名字;
 
//线程共享所有的票
(1)改成静态的;
(2)用一个窗口,启动三次;
 
1167156-20181130180459338-1026349170.png
 这个数据应该是被共享的;
1167156-20181130180459655-95001386.png
同一张票被多个线程卖出,没有规律;并发造成的;
 
1167156-20181130180500082-960289710.png
 a线程执行完1以后没有来得及执行第2句话,b线程进入;
 
1167156-20181130180500789-329675962.png
 
 
1167156-20181130180501739-1954302530.png
   synchronized(Object);
   Object称为对象锁;Object类比门;
   线程排队-线程等待池-blocked
   直到对象锁被打开;
 
  
1167156-20181130180502117-511227773.png
 同步代码块; this 就是对象锁,代表对象本身;
 
 
1167156-20181130180502559-1917049077.png
 有对象锁,线程的并发已经被控制住,会按照顺序卖;
 ---------------------------
 对象锁有0和1标志位,默认1,门打开,进入代码块使用;
 在进入的时候,会把标志位,变为0,门被锁上;
 
 如果1进入,1会被放到等待池里排队;
 如果2进入,2会先看等待池,有,在等待池排队;
 0号执行完,离开,把标志位重置为1,否则,会死锁:
 
1167156-20181130180502903-919357153.png
死锁:线程互读,并且并发;
 ------------------------------------------
 
 线程--区别
 线程--继承Thread VS 实现Runnable的区别
    从java的设计来看,通过继承Thread或者实现Runnable接口来创建线程本质上没有区别,从jdk帮助文档我们可以看到 Thread类本身就实现了Runnable接口,如果一定要说它们有
什么区别,总结几点:
1、尽可能使用实现Runnable接口的方式来创建线程
2、在使用Thread的时候只需要new一个实例出来,调用start()方法即可以启动一个线程,如:    Thread test=new Thread();
        test.start();
3、在使用Runnable的时候需要先new一个实现Runnable的实例,之后用Thread调用,如:
    Test implements Runnable
    Test t=new Test();
    Thread test=new Thread(t);
    tset.start();
线程--深入理解
线程对象只能启动一个线程,见[Thread04.java]
/** * 功能:使用线程的注意事项 * 不论继承Thread或实现Rnunable接口都不能使用start启同一个线程2次 */ public class Thread04 { public static void main(String[] args) { Cat cat1=new Cat(); cat1.start(); //cat1.start();同一个线程,不能启动2次 Dog dog1=new Dog(); Thread t=new Thread(dog1); t.start(); //t.start();同一个线程,不能启动2次 } } //猫类 class Cat extends Thread{ public void run(){ System.out.println("11"); } } //狗类 class Dog implements Runnable{ public void run(){ System.out.println("2"); } }
xxxxxxxxxx
31
 
1
/**
2
* 功能:使用线程的注意事项
3
* 不论继承Thread或实现Rnunable接口都不能使用start启同一个线程2次
4
*/
5
public class Thread04 {
6
public static void main(String[] args) {
7
Cat cat1=new Cat();
8
cat1.start();
9
//cat1.start();同一个线程,不能启动2次
10
 
11
Dog dog1=new Dog();
12
Thread t=new Thread(dog1);
13
t.start();
14
//t.start();同一个线程,不能启动2次
15
}
16
}
17
 
18
//猫类
19
class Cat extends Thread{
20
public void run(){
21
System.out.println("11");
22
}
23
}
24
 
25
//狗类
26
class Dog implements Runnable{
27
public void run(){
28
System.out.println("2");
29
}
30
}
31
 
1167156-20181130180503260-993523481.png
 
--------------------------------------------------------- 
结论:不管是通过继承Thread,还是通过实现Runnable接口创建线程,它们的一个对象只能启动(即:start())一次。否则就会有异常抛出。
两种创建线程的方法的区别
创建线程有两种方法:1、继承Thread;2、实现Runnable接口;
这两种方法有什么区别?
用实现Runnable接口的特点
1、用实现Runnable接口的方法创建对象可以避免java单继承机制带来的局限;
2、用实现Runnable接口的方法,可以实现多个线程共享同一段代码(数据);
因此建议大家如果你的程序有同步逻辑需求,则使用Runnable的方法来创建线程。
java线程的同步--提出问题
多线程的并发,给我们编程带来很多好处,完成更多更有效率的程序。但是也给我们带来线程安全问题。
java线程的同步--解决问题
解决问题的关键就是要保证容易出问题的代码的 原子性,
所谓原子性就是指:当a线程在执行某段代码的时候,别的线程必须等到a线程执行完后,它才能执行这段代码。也就是排队一个一个解决。
java处理线程两步的方法非常简单,只需要在需要同步的代码段,用:
   
synchronized(Object){你要同步的代码}
即可。
 售票案例演示[Thread05.java]
/** * 功能:使用线程的注意事项 * 线程并发同步锁synchronized(Object){}的使用 */ public class Thread05 { public static void main(String[] args) { //定义一个售票窗口 TicketWindow tw1=new TicketWindow(); //使用三个线程同时启动 Thread t1=new Thread(tw1); Thread t2=new Thread(tw1); Thread t3=new Thread(tw1); t1.start(); t2.start(); t3.start(); } } //售票窗口类 class TicketWindow implements Runnable { //共有2000张票 private int nums=2000; private Dog myDog=new Dog(); public void run() { while(true){ //出票速度是1秒出一张 try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } //认为if else要保证其原子性 //先判断是否还有票 synchronized(myDog){//synchronized(this){}为同步代码块 if(nums>0){ //显示售票信息 //Thread.currentThread().getName()得到当前线程的名字 System.out.println(Thread.currentThread().getName()+"正在售出第"+nums+"张票"); nums--; }else{ //售票结束 break; } } } } } class Dog{ }
 
1
/**
2
* 功能:使用线程的注意事项
3
* 线程并发同步锁synchronized(Object){}的使用
4
*/
5
public class Thread05 {
6
public static void main(String[] args) {
7
//定义一个售票窗口
8
TicketWindow tw1=new TicketWindow();
9
 
10
//使用三个线程同时启动
11
Thread t1=new Thread(tw1);
12
Thread t2=new Thread(tw1);
13
Thread t3=new Thread(tw1);
14
 
15
t1.start();
16
t2.start();
17
t3.start();
18
}
19
}
20
 
21
//售票窗口类
22
class TicketWindow implements Runnable {
23
//共有2000张票
24
private int nums=2000;
25
private Dog myDog=new Dog();
26
 
27
public void run() {
28
while(true){
29
//出票速度是1秒出一张
30
try {
31
Thread.sleep(1000);
32
} catch (Exception e) {
33
e.printStackTrace();
34
}
35
 
36
//认为if else要保证其原子性
37
//先判断是否还有票
38
synchronized(myDog){
//synchronized(this){}为同步代码块
39
if(nums>0){
40
//显示售票信息
41
//Thread.currentThread().getName()得到当前线程的名字
42
System.out.println(Thread.currentThread().getName()+"正在售出第"+nums+"张票");
43
nums--;
44
}else{
45
//售票结束
46
break;
47
}
48
}
49
}
50
}
51
}
52
 
53
class Dog{
54
}
55
 
1167156-20181130180503718-683733009.png
 
------------------------------------
java线程的同步--解决问题
对同步机制的解释:
java任意类型的对象都有一个标志位,该标志位具有0、1两种状态,其开始状态为1,当某个线程执行了synchronized(Object)语句后,object对象的标志位变为0的状态,直到执行完整个synchronized语句中的代码块后,该对象的标志位又回到1状态。
    当一个线程执行到synchronized(Object)语句的时候,先检查Object对象的标志位,如果为0状态,表明已经有另外的线程正在执行synchronized包括的代码,那么这个线程将暂时阻塞,让出CPU资源,直到另外的线程执行完相关的同步代码,并将Object对象的标志位变为状态,这个线程的阻塞就被取消,线程能继续运行,该线程又将Object的标志位变为0状态,防止其它的线程再进入相关的同步代码块中。
如果有多个线程因等待同一个对象的标志位面而处于阻塞状态时,当该对象的标志位恢复到1状态时,只会有一个线程能够进入同步代码执行,其它的线程仍处于阻塞的状态。
特别说明:
1、上面所说的标志位用术语讲就是对象锁,文件锁。数据库会有行锁、表锁等
2、synchronized(object)//object(就是对象锁)可以是任意类型对象
  
 
 

转载于:https://www.cnblogs.com/xuxaut-558/p/10045751.html

你可能感兴趣的文章
第六周
查看>>
解释一下 P/NP/NP-Complete/NP-Hard 等问题
查看>>
javafx for android or ios ?
查看>>
微软职位内部推荐-Senior Software Engineer II-Sharepoint
查看>>
sql 字符串操作
查看>>
【转】Android布局优化之ViewStub
查看>>
网络安全管理技术作业-SNMP实验报告
查看>>
根据Uri获取文件的绝对路径
查看>>
Flutter 插件开发:以微信SDK为例
查看>>
.NET[C#]中NullReferenceException(未将对象引用到实例)是什么问题?如何修复处理?...
查看>>
边缘控制平面Ambassador全解读
查看>>
Windows Phone 7 利用计时器DispatcherTimer创建时钟
查看>>
程序员最喜爱的12个Android应用开发框架二(转)
查看>>
vim学习与理解
查看>>
DIRECTSHOW在VS2005中PVOID64问题和配置问题
查看>>
MapReduce的模式,算法以及用例
查看>>
《Advanced Linux Programming》读书笔记(1)
查看>>
zabbix agent item
查看>>
一步一步学习SignalR进行实时通信_7_非代理
查看>>
AOL重组为两大业务部门 全球裁员500人
查看>>