线程的方法:
.isAlive():判断线程是否还活着,即线程是否还未中止。
.getPriority():获得线程的优先级数值。
.setPriority():设置线程的优先级。
.setName():设置线程的名字。
.getName():获取线程名字。
.currentThread():获取当前正在运行的线程对象。 public class MyThread implements Runnable {
private boolean flag =true;
private int num =;
@Override
public void run() {
while(flag){
System.out.println(Thread.currentThread().getName()+"-->"+num++);
}
}
public void stop(){//停止线程的方法
this.flag=!this.flag;
}
} /**
Thread.currentThread() :当前线程
setName():设置名称
getName():获取名称
isAlive():判断状态
*/
public class InfoDemo01 {
public static void main(String[] args) throws InterruptedException {
MyThread it =new MyThread();
Thread proxy =new Thread(it,"挨踢");
proxy.setName("test");
System.out.println(proxy.getName());
//Thread.currentThread()的currentThread()是一个静态方法,写在哪个线程里面就代表哪个线程。
System.out.println(Thread.currentThread().getName()); //main proxy.start();
System.out.println("启动后的状态:"+proxy.isAlive());
Thread.sleep();//main阻塞,proxy仍然在跑。
it.stop();//cpu不一定马上停止它,它有延缓的时间。
Thread.sleep();
System.out.println("停止后的状态:"+proxy.isAlive());
}
} /**
* 优先级:概率,不是绝对的先后顺序
MAX_PRIORITY 10
NORM_PRIORITY 5 (默认)
MIN_PRIORITY 1 setPriority()
getPriority()
*/
public class InfoDemo02 {
public static void main(String[] args) throws InterruptedException {
MyThread it1 =new MyThread();
Thread p1 =new Thread(it1,"挨踢1");
MyThread it2 =new MyThread();
Thread p2 =new Thread(it2,"挨踢2"); p1.setPriority(Thread.MIN_PRIORITY); //设置优先级,优先级高则执行的概率高。
p2.setPriority(Thread.MAX_PRIORITY);//设置优先级
p1.start();
p2.start(); Thread.sleep();
it1.stop();
it2.stop();
}
} 线程的同步(获得方法的锁):
同步也称为并发,由于有多条路径,就存在多个线程访问同一个资源,为了确保这份资源安全,因此对其加入同步,因此就是线程安全。
线程安全与不安全是在多线程访问的情况下,是为了确保资源正确。
synchronized代码块处多个线程进来的时候只能一个一个线程的通过这个代码处,其余线程只能等待前一个线程运行完这个代码处后才能运行这个代码,否则线程只能在这个代码处停止执行。 synchronized -> 任何线程访问这个方法要先获得这个方法的锁。 .同步块
synchronized(引用类型|this|类.class){} .同步方法
synchronized声明方法。
/*凡是线程安全的效率会低,看到效率低的用时长的则线程安全反之时间短的不安全*/
public class SynDemo01 {
public static void main(String[] args) {
//真实角色
Web12306 web= new Web12306();
//3个代理,代理的是同一份资源Web12306的对象web。
Thread t1 =new Thread(web,"路人甲");
Thread t2 =new Thread(web,"黄牛已");
Thread t3 =new Thread(web,"攻城师");
//启动线程
t1.start();
t2.start();
t3.start();
}
} /**
* 线程安全的类
*/
class Web12306 implements Runnable {
private int num =;
private boolean flag =true;
@Override
public void run() {
while(flag){
test1();test2();test3();test4();test5();test6();
}
} public void test6(){ if(num<=){
flag=false; //跳出循环
return ;
}
//a b c
synchronized(this){
try {
Thread.sleep(); //模拟 延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
}
} //线程不安全 锁定资源不正确
public void test5(){
//a b c
synchronized((Integer)num){//int是基本类型要手动包装成引用类型才能通过语法检查,所以一般要锁定共同访问的资源对象。
if(num<=){
flag=false; //跳出循环
return ;
}
try {
Thread.sleep(); //模拟 延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
}
} //锁定范围过小 线程不安全
public void test4(){
//num=1,abc都在这里等,a进去出来后,b再进去,
synchronized(this){
//b
if(num<=){
flag=false; //跳出循环
return ;
}
}
//a出来了b进去了,由于下面有延时a仍然在等,有可能ab同时到达此处,故num会减2次。所以num会为0.
try {
Thread.sleep(); //模拟 延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
}//a -->1 //线程安全 锁定正确
public void test3(){
//a b c
synchronized(this){//同步块,this形参只能是引用类型。this指的是Web12306对象,Web12306对象在同一个时刻只能被一个线程使用。
if(num<=){
flag=false; //跳出循环
return ;
}
try {
Thread.sleep(); //模拟 延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
}
}
//线程安全 锁定正确,效率低因为有等待,一个线程进入这个方法后其余线程只能等待。
public synchronized void test2(){//a.b.c3个线程同时访问这个方法,a拿到锁,a出去之后bc才能进来。
if(num<=){
flag=false; //跳出循环
return ;
}
try {
Thread.sleep(); //模拟 延时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
} //线程不安全
public void test1(){
if(num<=){//num=1时,当a、b、c,d依次进来后依次开始睡眠。
flag=false; //跳出循环
return ;
}
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
}//a醒了以后带走了1,b醒了以后带走了0,c醒了以后带走了-1,d醒了以后带走了-2。
} 单例设计模式:
对象由类内部自己创建,外部只能使用这一个对象。确保一个类只有一个对象,外部不能创建对象。
垃圾回收gc只有一个,在任何地方都是对其引用而已。
单例设计模式步骤:
、构造器私有化,避免外部直接创建对象
、声明一个私有的静态变量
、创建一个对外的公共的静态方法 访问该变量,如果变量没有对象,创建该对象 /**
* 在单线程里面,创建的多个单例的对象的地址是一样的,
* 多线程的时候要想创建的单例对象是同一个则要在单例中创建这个对象的时候加入同步。
*/
/**
* 单例设计模式:确保一个类只有一个对象
*/
public class SynDemo02 {
public static void main(String[] args) {
JvmThread thread1 = new JvmThread();
JvmThread thread2 = new JvmThread();
thread1.start();
thread2.start();
}
}
class JvmThread extends Thread{
private long time;
public JvmThread() {
}
public JvmThread(long time) {
this.time =time;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->创建:"+Jvm.getInstance(time));
}
} /**
* 单例设计模式
* 外部使用时确保一个类只有一个对象,对象由类内部自己创建,外部只能使用这一个对象,外部不能创建对象。
* 懒汉式 ,getInstance()是经典的双重检查。
* 1、构造器私有化,避免外部直接创建对象
* 2、声明一个私有的静态变量
* 3、创建一个对外的公共的静态方法 访问该变量,如果变量没有对象,创建该对象
*/
class Jvm {
//声明一个私有的静态变量
private static Jvm instance =null;
//构造器私有化,避免外部直接创建对象
private Jvm(){//自己写了就不会自动创建了,不管你写的是有参还是无参的构造器。 }
//创建一个对外的公共的静态方法 访问该变量,如果变量没有对象,创建该对象
public static Jvm getInstance(long time){
// c d e -->效率 提供 已经存在对象的访问效率
if(null==instance){//这里加判断是为了如果对象已经存在则直接取,不用进同步快,因为同步快要等。
// a b,如果对象不存在则要创建对象,创建对象的时候为了避免多个线程创建多个对象则要加同步快,
synchronized(Jvm.class){//静态方法里面没有this,因为this是这个对象,静态方法时还没有对象。
if(null==instance ){//这里判空是开始没有对象的时候多个线程进入同步快代码之上,有一个进来后创建了,另一个进来后就不用创建了。
try {
Thread.sleep(time); //延时 ,放大错误
} catch (InterruptedException e) {
e.printStackTrace();
}
instance =new Jvm();
}
}
}//a
return instance;
} public static Jvm getInstance3(long time){//效率不高,和锁住方法的效率差不多。
//a b c d e -->效率不高 c 因为存在对象也需要等待,任何时候获取这个对象都需要等待。
synchronized(Jvm.class){
if(null==instance ){
try {
Thread.sleep(time); //延时 ,放大错误
} catch (InterruptedException e) {
e.printStackTrace();
}
instance =new Jvm();
}
return instance;
}
} public static Jvm getInstance1(long time){//没有加同步,多个线程会创建多个单例的对象。
if(null==instance ){
//a,b同时进来则会创建多个对象。
try {
Thread.sleep(time); //延时 ,放大错误
} catch (InterruptedException e) {
e.printStackTrace();
}
instance =new Jvm();
}
return instance;
} public static synchronized Jvm getInstance0(long time){//锁住方法,效率低。
if(null==instance ){
try {
Thread.sleep(time); //延时 ,放大错误
} catch (InterruptedException e) {
e.printStackTrace();
}
instance =new Jvm();
}
return instance;
} } 任何一个类在jvm或者类加载器中都有一个模板,只要你用到它再去这个模板里面访问。 /**
* 单例创建的方式
* 1、懒汉式
* 1)、构造器私有化
* 2)、声明私有的静态属性
* 3)、对外提供访问属性的静态方法,确保该对象存在
*/
public class MyJvm {
private static MyJvm instance;
private MyJvm(){
}
public static MyJvm getInstance (){
if(null==instance){ //这是为了提供效率,有这个对象则直接取。
synchronized(MyJvm.class){
if(null==instance){ //这是为了安全,多个线程进来之后保证只创建一个对象。
instance =new MyJvm();
}
}
}
return instance;
}
}
/**
* 饿汉式
1)、构造器私有化
* 2)、声明私有的静态属性,同时创建该对象
* 3)、对外提供访问属性的静态方法
*/
class MyJvm2 {
private static MyJvm2 instance =new MyJvm2();//类加载时创建
private MyJvm2(){
}
public static MyJvm2 getInstance (){
return instance;
}
}
/**
* 类在使用的时候加载 ,延缓加载时间
*/
class MyJvm3 {//加载MyJvm3时不会加载JVMholder类。
private static class JVMholder{//内部类
private static MyJvm3 instance =new MyJvm3();
}
private MyJvm3(){
}
//加载MyJvm3时还没有调用还没有调用getInstance (),就没有涉及JVMholder类,
//调用getInstance ()方法时涉及JVMholder类就会加载JVMholder类,同时生成MyJvm3的实例。
public static MyJvm3 getInstance (){
return JVMholder.instance;
}
} 过多的同步方法可能造成死锁:
/**
* 过多的同步方法可能造成死锁
* 一手给钱一手给货,你不给钱我不给货,你不给货我不给钱。
*/
public class SynDemo03 {
public static void main(String[] args) {
Object g =new Object();
Object m = new Object();
//同步同一份资源g、m
Test1 t1 =new Test1(g,m);
Test2 t2 = new Test2(g,m);
Thread proxy1 = new Thread(t1);
Thread proxy2 = new Thread(t2);
proxy1.start();//t1的run方法
proxy2.start();//t2的run方法
} }
class Test1 implements Runnable{
Object goods ;
Object money ; public Test1(Object goods, Object money) {
super();
this.goods = goods;
this.money = money;
} @Override
public void run() {
while(true){
test();
}
} public void test(){
synchronized(goods){
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(money){
} }
System.out.println("一手给钱");
}
} class Test2 implements Runnable{
Object goods ;
Object money ;
public Test2(Object goods, Object money) {
super();
this.goods = goods;
this.money = money;
} @Override
public void run() {
while(true){
test();
}
} public void test(){
synchronized(money){
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(goods){ } }
System.out.println("一手给货");
}
} 生产者消费者模式(解决多线程死锁的问题):
要么生产者生产消费者等待,要么消费者消费生产者等待。 信号灯法: /**
一个场景,共同的资源
生产者消费者模式-- 信号灯法
wait() :等待,释放锁 ,
sleep(): 不释放锁,
notify()/notifyAll():唤醒,
wait()和notify()/notifyAll()只能 与 synchronized一起使用。
*/
public class Movie {//电影类
private String pic ;
//信号灯
//flag -->T 生产生产,消费者等待 ,生产完成后通知消费
//flag -->F 消费者消费 生产者等待, 消费完成后通知生产
private boolean flag =true;
/**
* 播放
* @param pic
*/
public synchronized void play(String pic){
if(!flag){ //生产者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//开始生产
try {
Thread.sleep();//生产耗费了500毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产了:"+pic);
//生产完毕
this.pic =pic;
//通知消费
this.notify();//唤醒等待线程
//生产者停下
this.flag =false;
} public synchronized void watch(){
if(flag){ //消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//开始消费
try {
Thread.sleep();//消费所花时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费了"+pic);
//消费完毕
//通知生产
this.notifyAll();//唤醒等待线程
//消费停止
this.flag=true;
}
} /**
* 生产者
*/
public class Player implements Runnable {
private Movie m ; public Player(Movie m) {
super();
this.m = m;
} @Override
public void run() {
for(int i=;i<;i++){
if(==i%){
m.play("左青龙");
}else{
m.play("右白虎");
}
}
}
} /**
* 消费者
*/
public class Watcher implements Runnable {
private Movie m ; public Watcher(Movie m) {
super();
this.m = m;
} @Override
public void run() {
for(int i=;i<;i++){
m.watch();
}
}
} public class App {
public static void main(String[] args) {
//共同的资源
Movie m = new Movie(); //多线程对同一份资源的访问
Player p = new Player(m);
Watcher w = new Watcher(m); new Thread(p).start();
new Thread(w).start();
/*生产了:左青龙
消费了左青龙
生产了:右白虎
消费了右白虎
生产了:左青龙
消费了左青龙
生产了:右白虎
消费了右白虎
生产了:左青龙
消费了左青龙
生产了:右白虎
消费了右白虎
生产了:左青龙
消费了左青龙*/
}
}

java17 线程的方法的更多相关文章

  1. Qt新建线程的方法(四种办法,很详细,有截图)

    看了不少Qt线程的东西,下面总结一下Qt新建一个线程的方法. 一.继承QThread 继承QThread,这应该是最常用的方法了.我们可以通过重写虚函数void QThread::run ()实现我们 ...

  2. Qt新建线程的方法(有QRunnable,QThreadPool,moveToThread和QtConcurrent的例子)

    看了不少Qt线程的东西,下面总结一下Qt新建一个线程的方法. 一.继承QThread 继承QThread,这应该是最常用的方法了.我们可以通过重写虚函数void QThread::run ()实现我们 ...

  3. 远程线程注入方法CreateRemoteThread

    最近在整理学习Windows注入方面的知识,这个远程注入前面早写过,现在看看人家博客的理解整理,整理, 需要源码的可以到我的github上下载. 链接是  https://github.com/Ars ...

  4. Thread线程join方法自我理解

    Thread线程join方法自我理解 thread.join():等待thread线程运行终止,指的是main-thread(main线程)必须等待thread线程运行结束,才能继续thread.jo ...

  5. Android多线程编程<一>Android中启动子线程的方法

          我们知道在Android中,要更新UI只能在UI主线程去更新,而不允许在子线程直接去操作UI,但是很多时候,很多耗时的工作都交给子线程去实现,当子线程执行完这些耗时的工作后,我们希望去修改 ...

  6. 多线程之间的通信(等待唤醒机制、Lock 及其它线程的方法)

    一.多线程之间的通信. 就是多个线程在操作同一份数据, 但是操作的方法不同. 如: 对于同一个存储块,其中有两个存储位:name   sex, 现有两个线程,一个向其中存放数据,一个打印其中的数据. ...

  7. java创建线程的方法

    1.1      创建线程 1.1.1     无返回值的线程创建 package com.first; public class ThreadTest { public static void ma ...

  8. OkHttp3几个简单的例子和在子线程更新UI线程的方法

    okHttp用于android的http请求.据说很厉害,我们来一起尝尝鲜.但是使用okHttp也会有一些小坑,后面会讲到如何掉进坑里并爬出来. 首先需要了解一点,这里说的UI线程和主线程是一回事儿. ...

  9. iOS中安全结束 子线程 的方法

    一个典型的结束子线程的方法:   用 isFinished 检测子线程是否被完全kill掉 -(IBAction)btnBack:(id)sender { //释放内存 仅仅remove 并不会触发内 ...

随机推荐

  1. [jobdu]二叉树的镜像

    树的镜像,这里的做法就是先序遍历的反过来呗. #include <iostream> #include <vector> using namespace std; void p ...

  2. UDP模块(黑胶体)

    UDP模块是采用PIP封装技术的U盘半成品模块,直接加上外壳,就是成品U盘. 它有以下特点: 防水.防尘.防震. 一体WAFER封装技术. 薄.轻.时尚. 产品装配方便.简单. 产品标准化,适合客户在 ...

  3. oracle database resident connection pooling(驻留连接池)

    oracle在11g中引入了database resident connection pooling(DRCP).在此之前,我们可以使用dedicated 或者share 方式来链接数据库,dedic ...

  4. ORACLE查看锁(lock)情况

      SELECT /*+ RULE */         ls.osuser os_user_name,          ls.username user_name,          DECODE ...

  5. 如何删除已上线的IAP项

    cleared for sale to NO. then Delete.

  6. 理解SVG坐标系统和变换: 建立新视窗

    在SVG绘制的任何一个时刻,你可以通过嵌套<svg>或者使用例如<symbol>的元素来建立新的viewport和用户坐标系.在这篇文章中,我们将看一下我们如何这样做,以及这样 ...

  7. HDU 1695 GCD 莫比乌斯反演

    分析:简单的莫比乌斯反演 f[i]为k=i时的答案数 然后就很简单了 #include<iostream> #include<algorithm> #include<se ...

  8. [Irving] Ext.Net动态添加GridPanel列绑定Checkbox值失败的解决办法

    var grid = X.GetCmp<GridPanel>(vm.GRID_QUOTATIONS_FEEITEM_RANGE_SHOW); grid.AddColumn(Html.X() ...

  9. Spring mvc get和post传值乱码问题

    1.url拼值 传单值 对象 list  map都是用json的格式传入后台 <%@ page language="java" contentType="text/ ...

  10. 三种情形容易引起Azure虚拟机重新启动

      与虚拟机或云服务角色中运行的代码有关的问题可能会导致重新启动.但是,Microsoft 在以下情况下也会重新启动您的角色: 来宾操作系统更新 – 仅影响云服务 Web 和辅助角色.有关如何限制这些 ...