博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java-多线程总结
阅读量:5056 次
发布时间:2019-06-12

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

 1.调用run和调用start有什么区别

   run方法只是类里的一个普通方法,调用该方法只是执行该方法里的代码,程序中还是只有主线程这一线程

   而start方法是将该线程变成可运行状态(还没运行),等待cpu切换来时就可以启动执行该线程下的run方法。

   即start方法可以启动线程,而run方法只是Thread的一个普通方法。

2.静态的同步方法与其他同步代码块之间的同步

   静态同步方法:public static synchronized void method(){...};

                      //它的同步锁是该方法所属字节码文件对象即 类名.getClass()或 类名.class

   所以与它同步的代码块里必须是:synchronized(类名.class) {.....}

   非静态的方法的同步锁是this对象本身

3.总结

  • 同步的好处:解决了线程的安全问题。
  • 同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。
  • 同步的前提:同步中必须有多个线程并使用同一个锁

4.wait 和 sleep 区别?

  1. wait可以指定时间也可以不指定。sleep必须指定时间。
  2. 在同步中时,对cpu的执行权和锁的处理不同。  wait:释放执行权,释放锁。  sleep:释放执行权,不释放锁。

5.wait,notify,notifyAll方法使用

   这三个方法经常用在线程间的通信,比如:X线程对某个数据进行一次更改后,Y线程对其读取一次,是一次更改一次读取交替进行,

   不是更改多次后再读取多次。它们只能在同步方法或同步代码块中调用,且同步锁必须为这三个方法的共同对象。无论线程调用一个

   对象的wait还是notify方法,该线程必须先得到该对象的锁,才可以调用该方法。notify只能唤醒同一个对象监视器中调用wait的线程。

   以下是,生产者生产(更改)一次后,换消费者消费(读取)一次。依次交替。

 

package hq.Thread.Test;public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Q q=new Q (); Consumer c=new Consumer(q); Producer p=new Producer (q); new Thread (c).start(); new Thread (p).start(); } } //消费者线程(读取) class Consumer implements Runnable { private Q q=null; public Consumer (Q q) { this.q=q; } public void run () { while(true) { //System.out.println(Thread.currentThread().getName()); try { q.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //生产者线程(更改) class Producer implements Runnable { private Q q=null; private int num=1; public Producer (Q q) { this.q=q; } public void run () { while(true) { //System.out.println(Thread.currentThread().getName()); if(num==1) { try { q.put("陈奕迅","男"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if(num==0) { try { q.put("王菲","女"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } num=(num+1)%2; } } } //共同操作的数据Q,由线程对其进行修改,读取, //因为要修改和读取同步(即两个方法的同步锁为Q对象),且数据在Q内部,所以应具有操作数据的方法 class Q { private String name; private String sex; private boolean flag=true;//以标志位来控制更改或读取操作。 //更改的同步方法 public synchronized void put(String name,String sex) throws InterruptedException { //默认标志位为true时更改否则等待 if(!isFlag()) wait(); this.name=name; this.sex=sex; //更改完后换读取,且唤醒读取(为false标志)的线程 this.flag=false; notify(); System.out.println(Thread.currentThread().getName()); } //读取的同步方法 public synchronized void get() throws InterruptedException { //默认标志位为flase时读取否则等待 if(isFlag()) wait(); System.out.println(this.name+":"+this.sex); //读取完后换更改,且唤醒更改(为true)的线程 this.flag=true; notify(); System.out.println(Thread.currentThread().getName()); } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag=flag; } public String getName() { return name; } public void setName(String name) { this.name=name; } public String getSex() { return sex; } public void getSex(String sex) { this.sex=sex; } }

 

转载于:https://www.cnblogs.com/beyondbycyx/p/4234077.html

你可能感兴趣的文章
JDK JRE Java虚拟机的关系
查看>>
OA项目设计的能力③
查看>>
VueJS ElementUI el-table 的 formatter 和 scope template 不能同时存在
查看>>
Halcon一日一练:图像拼接技术
查看>>
iOS设计模式 - 中介者
查看>>
centos jdk 下载
查看>>
HDU 1028 Ignatius and the Princess III(母函数)
查看>>
多变量微积分笔记24——空间线积分
查看>>
poi操作oracle数据库导出excel文件
查看>>
(转)Intent的基本使用方法总结
查看>>
java容器---------手工实现Linkedlist 链表
查看>>
《梦断代码》读书笔记(三)
查看>>
FreeMarker解析json数据
查看>>
Java8 Lambda表达应用 -- 单线程游戏server+异步数据库操作
查看>>
Codeforces 450 C. Jzzhu and Chocolate
查看>>
[Unity3D]Unity3D游戏开发MatchTarget的作用攀登效果实现
查看>>
ACdream 1115 Salmon And Cat (找规律&&打表)
查看>>
AngularJS学习篇(一)
查看>>
关于Xshell无法连接centos6.4的问题
查看>>
css3动画——基本准则
查看>>