JAVA 10(多线程)

创建线程:
通过对java.lang包的查找,继承Thread类可以创建线程
1,建立类继承Thread类
2,复写Thread中的ran方法。
3,调用线程的start()方法,该方法的作用是,启动线程,调用ran方法。
public class Test {
public static void main(String args[])
{
Demo a= new Demo();
a.start();
for(int x=0;x<=100;x++)
System.out.println("hello word");
}
}
class Demo extends Thread
{
public void ran()
{
for(int x=0;x<=100;x++)
System.out.println("Demo ran");
}
}
两个输出会交替出现。
发现运行结果每次都不同
因为多个线程都在获取cpu的使用权,cpu执行到谁,谁就运行,在某一时刻,只能有一个程序在运行(多核除外)cpu在做着快速切换,已达到看上去是在同时运行。
多线程特性:随机性,谁抢到谁执行,至于执行多长时间,cpu说的算。
为什么要覆盖ran方法
thread类用于描述线程。
该类定义了用于存储要运行的代码,这些代码就存储在ran方法中。
ran() 和 start() 区别
只写ran()线程没有被创建,编程了单线程程序。会顺序执行,输出不是随机的。
 
线程运行过程中的状态:
线程对象的名称:
每个线程都有默认名称。
Thread-编号   //该编号从0开始
线程名称可以提供 线程.getName()  方法获得
currentThread() :获取当前运行的线程对象
getName():获取线程名称
买票程序举例:
public class Test
{
public static void main(String args [])
{
Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
Ticket t3 = new Ticket();
Ticket t4 = new Ticket();
Ticket t5 = new Ticket();
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
class Ticket extends Thread
{
private static int tick=100; //静态,所有对象公用一个票数。
public void run()
{
if(tick>0)
System.out.println(currentThread().getName()+"sale:"+tick--);
}
}
第二种创建进程的方法
 
实现runable接口
步骤:
1,定义类,实现runnable接口
2,覆盖runnable中的run()方法
3,通过Thread;类建立线程对象
4,将Runnable接口对象作为实际参数传递给Thread类的构造函数
5,调用Thread类的start方法开启线程并调用Runnable子类中的run方法
实现方式和前一种方法的区别:
实现方式好处在于:避免了单继承的局限性。
在定义线程时,建议使用实现方式。
继承Thread类:线程代码存放在Thread子类对象run方法中
实现Runnable:线程代码存放在接口的子类对象的run中
在此例中ticket也不用static了,因为只建立了一个对象
睡眠:
try
{Thread.sleep(10);}
catch(Exception e)
{
}
public class Test
{
public static void main(String args [])
{
Ticket t = new Ticket();
Thread t1 =new Thread(t);
Thread t2 =new Thread(t);
Thread t3 =new Thread(t);
Thread t4 =new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Ticket implements Runnable
{
private int tick = 100;
public void run()
{
while(true)
if(tick>0)
{
System.out.println("sale"+tick--);
}
}
}
安全问题:
以下代码会打印  0,-1,-2号票
产生问题原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,另一个线程1参与进来执行,导致共享数据出现错误。 
解决办法:对多条操作共享数据的语句,只能让让一个线程都执行完,在执行过程中,其他线程不可以参与执行。 
java对于多线程的安全问题提供了专业的解决方式,就是同步代码块。会保证该代码块内的代码被全部执行再切换线程。
格式:
synchronized(对象)
{
需要被同步的代码
}
public class Test
{
public static void main(String args [])
{
Ticket t = new Ticket();
Thread t1 =new Thread(t);
Thread t2 =new Thread(t);
Thread t3 =new Thread(t);
Thread t4 =new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Ticket implements Runnable
{
private int tick = 100;
public void run()
{
while(true)
if(tick>0)
{
try
{Thread.sleep(10);}
catch(Exception e)
{
}
System.out.println("sale"+tick--);
}
}
}
修改安全问题后的代码
public class Test
{
public static void main(String args [])
{
Ticket t = new Ticket();
Thread t1 =new Thread(t);
Thread t2 =new Thread(t);
Thread t3 =new Thread(t);
Thread t4 =new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Ticket implements Runnable
{
Object obj= new Object();
private int tick = 100;
public void run()
{
while(true)
{
synchronized(obj)
{
if(tick>0)
{
try
{Thread.sleep(10);}
catch(Exception e)
{
}
System.out.println("sale"+tick--);
}
}
}
}
}
如何找到安全问题/同步的前提:
1,明确哪些代码是多线程运行的代码。
2,明确共享数据。
3,明确多线程代码中哪些语句是操作共享数据的。
同步函数:
同步有两种,1代码块,2同步函数
用synchronized修饰函数即可。
同步代码块使用的锁时obj
同步函数的锁:
同步函数使用的所时this  也就是调用该函数的实体。
如果同步函数被静态修饰后,使用的锁是该类对应的class,就是类名点class 。   Ticket.class
懒汉式
死锁:
 
两个锁:
同步中嵌套同步,锁却不同,恰好停止在某位置,会造成死锁。
要避免死锁。
public class Test
{
public static void main(String args [])
{
Thread t1 = new Thread(new Deadlock(true));
Thread t2 = new Thread(new Deadlock(false));
t1.start();
t2.start();
}
}
class Deadlock implements Runnable
{
private boolean flag;
Deadlock(boolean flag)
{
this.flag = flag;
}
public void run()
{
if(flag)
{
while(true)
{
synchronized(Mylock.locka)
{
System.out.println("if lock a");
synchronized(Mylock.lockb)
{
System.out.println("if lockb");
}
}
}
}
else
{
while(true)
{
synchronized(Mylock.lockb)
{
System.out.println("else lockb");
synchronized(Mylock.locka)
{
System.out.println("else locka");
}
}
}
}
}
}
class Mylock
{
static Object locka = new Object();
static Object lockb = new Object();
}

 

转载于:https://www.cnblogs.com/hitxx/p/4675974.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/288201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

地球空间与数字测绘知识总结

1、地理空间(geo-spatial) 一般指上至电离层,下至地壳与地幔交界的莫霍面之间的空间区域。上下大约有2000km。 2、自然球体 由地球自然表面所包围的形体称为地球自然形体。

(附)python3 只需3小时带你轻松入门——python常用一般性术语或词语的简单解释

术语一般解释dict 字典一种键值对的关系&#xff0c;一个键代表一个索引&#xff0c;一个键对应一个值index 索引在列表、数组、字典或一般容器中表示一个内容值的“地址”&#xff0c;通过索引可以获取值开发环境当前开发所需要的一些基本软件、硬件或操作系统list 列表一种数…

linux c之判断字符串是不是以另一字符串开始或者结尾

1 问题 判断字符串是不是以另一字符串开始或者结尾 2 代码实现 #include <stdio.h> #include <string.h>/***判断是字符串str是不是以start开始*/ int is_start_with(const char *str, char *start) {if (NULL == str || NULL == start){return -1;}int str_len …

联想台式计算机 不启动u盘,新电脑不识别u盘启动盘?不用送修,自己就能搞定!...

原标题&#xff1a;新电脑不识别u盘启动盘&#xff1f;不用送修&#xff0c;自己就能搞定&#xff01;新买的电脑想要通过u盘启动来装系统&#xff0c;但是一些用户却遇到难题了&#xff0c;以为制作好u盘启动盘就能直接开机启动了。殊不知&#xff0c;很多新电脑都是预装的win…

Hadoop(三)通过C#/python实现Hadoop MapReduce

MapReduceHadoop中将数据切分成块存在HDFS不同的DataNode中&#xff0c;如果想汇总&#xff0c;按照常规想法就是&#xff0c;移动数据到统计程序&#xff1a;先把数据读取到一个程序中&#xff0c;再进行汇总。但是HDFS存的数据量非常大时&#xff0c;对汇总程序所在的服务器将…

EntityFramework 动态构造排序 FuncIQueryableT, IOrderedQueryableT Dynamic

using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; /*** * jackchain * QQ:710782046* 2017-08-31* 动态构造OrderBy Linq序列* */namespace UFX.Tools {public class Convert…

hdu 5310 Souvenir

http://acm.hdu.edu.cn/showproblem.php?pid5310 题意&#xff1a;今天是BestCoder一周年纪念日. 比赛管理员Soda想要给每个参赛者准备一个纪念品. 商店里纪念品的单价是p 元, 同时也可以花q 元购买纪念品套装, 一个套装里有m 个纪念品. 今天总共有n 个参赛者, Soda想要知道最…

ArcGIS 10.2中栅格数据的属性表问题

什么条件下我们能在ArcGIS中看到栅格数据的属性表呢? 网上的说法是:对于单波段的整型ESRI GRID数据,如果它的像元值范围小于10万(max-min<1000000),并且少于500条唯一值,那么软件会为它创建一个“真正”的属性表存储在INFO文件夹的grid.VAT表格中。对于不满足上述条…

python简介及环境安装

Python的创始人为荷兰人吉多范罗苏姆 。1989年圣诞节期间&#xff0c;在阿姆斯特丹&#xff0c;Guido为了打发圣诞节的无趣&#xff0c;决心开发一个新的脚本解释程序&#xff0c;作为ABC语言的一种继承。 Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释…

剑指offer之求两个数之和(不能使用四则运算)

1 题目 剑指offer之求两个数之和(不能使用四则运算) 2 代码实现 #include<stdio.h>int add(int num1, int num2) {int sum1;int carry;do{sum1 (num1 ^ num2);carry (num1 & num2) << 1;num1 sum1;num2 carry;} while (carry ! 0);return num1; }int mai…

ZOJ 3879 Capture the Flag(模拟)

思路&#xff1a;恶心模拟...照着题目怎么说就怎么做就好了 #include<bits/stdc.h> using namespace std; const int maxn 100000; #define exp 1e-5 struct Node {int id,rank;double score; }nodes[105];int vis[105][105][105]; int visit[105]; bool cmp1(Node a,No…

晋中学院计算机考研,晋中学院有多少人死在考研路上

晋中学院有多少人死在考研路上(2011-05-23 20:34:30)标签&#xff1a;日记杂谈有一句话叫作&#xff1a;长江后浪推前浪,前浪死在沙滩上&#xff0c;用来形容少年老成与故人的可怜。转眼间到了谋取出路的时候了&#xff0c;班上几乎所有的人都在那里嚷嚷的要考研&#xff0c;但…

解决ArcGIS 9.3卸载时出现invalid install.log file的方法

地信君都知道,ArcGIS 9.3 License卸载时常出现“invalid install.log file”的错误提示,而导致卸载失败,如下:

Nodejs前端服务器压缩图片

Nodejs作为前端服务器&#xff0c;自然能承担处理图片的能力&#xff0c; 使用GM for nodejs 作为图片处理器&#xff0c;调用ImageMagick处理图片 使用ImageMagick var imageMagick gm.subClass({ imageMagick: true }); 然后就像文档中使用gm那样使用ImageMagick即可 &#…

人工神经网络心得体会_卷积神经网络学习心得

萌新小白一只&#xff0c;刚刚接触AI&#xff0c;在遍历人工智能发展时就看到了“卷积神经网络”&#xff0c;顿时想到了去年被概率论支配的恐惧&#xff0c;因此想在这里分享一点经验来帮助大家更好理解。所谓“卷积神经网络”&#xff0c;就是结合卷积公式&#xff0c;建立类…

使用virt-install安装kvm虚拟机时需要的问题

使用virt-install安装kvm虚拟机时需要的问题今天在做kvm的实验时&#xff0c;使用virt-install安装虚拟机的过程中遇到了一些问题&#xff0c;其中有一个问题弄了好久都没有弄好&#xff0c;不过现在已经好了。由于我使用virt-install命令安装虚拟机的&#xff0c;其命令如下&a…

样式和主题的区别(Styles and Themes)

参考资料&#xff1a; http://www.tuicool.com/articles/VfiUba http://android.blog.51cto.com/268543/303728/转载于:https://www.cnblogs.com/8dull/p/5387072.html

从同步函数 hello-world-dotnet 开始探索OpenFunction

OpenFunction[1] 是一个现代化的云原生 FaaS&#xff08;函数即服务&#xff09;框架&#xff0c;它引入了很多非常优秀的开源技术栈&#xff0c;包括 Knative、Tekton、Shipwright、Dapr、KEDA 等&#xff0c;这些技术栈为打造新一代开源函数计算平台提供了无限可能&#xff1…

剑指offer之股票的最大利润

1 问题 求股票的最大利润&#xff0c;简言之就是求一个数组里面元素差的最大值&#xff0c;要求时间复杂度O(n) 2 代码实现 #include <stdio.h> #include <stdlib.h>int maxDiff(int *number, int length) {if (NULL number || length < 2){return 0;}int mi…

【ArcGIS风暴】ArcGIS 10.2栅格计算器实用公式大全(经典珍藏版)

栅格计算器(Raster Calculator) 是一种空间分析函数工具,可以输入地图代数表达式,使用运算符和函数来做数学计算,建立选择查询,或键入地图代数语法。只有熟练的运用并记忆一些常用的公式,才能很好的运用栅格计算器。本文将常见的及一些容易出错的公式予以总结,方便学习…