一、并行、串行、并发
在了解java中多线程的三种实现方式之前,我们首先需要明白并行、串行、并发三个概念。
1.并行:多个CPU同时处理多个任务;
2.串行:单个CPU处理多个任务,当一个任务执行完成之后下一个任务才能够执行;
3.并发:单个CPU处理多个任务,每个任务都会被分一定的时间片,一个任务执行一段时间无论完成与否都要切换另一个任务执行。
在java中多线程其实就是并发的一种模式。
二、java实现多线程的三种方式
我们以买咖啡为例,现在咖啡店只有一个窗口,将每一个人买咖啡的过程视为一个任务。
1.实现Runnable接口
package multithreading;
public class LRunnableOne {
public static void buyCoffee(String name) {
System.out.println(name + "开始买咖啡");
System.out.println(name + "正在买咖啡");
System.out.println(name + "买完了");
}
public static void main(String[] args) {
Thread t1 = new Thread(new lr("张三"));
Thread t2 = new Thread(new lr("李四"));
Thread t3 = new Thread(new lr("王五"));
System.out.println("run方法并不会启动新的线程,只是执行线程中run内的方法,仍然是在主线程上依次上进行");
t1.run();
t2.run();
t3.run();
System.out.println("start方法会启动新的线程,并发执行");
t1.start();
t2.start();
t3.start();
}
}
class lr implements Runnable{
String name;
public lr(String name) {
this.name = name;
}
@Override
public void run() {
LRunnableOne.buyCoffee(name);
}
}

这里我们先是直接调用了run方法,又调用了start方法,这样做是为了说明start方法与run方法的不同。start方法是启动就绪的线程,然后调用线程内的run方法;run并不会启动线程,只是执行其中的方法体。start方法只能调用一次,但是run方法可以调用多次。
2.继承Thread类
package multithreading;
public class LThreadOne {
public static void buyCoffee(String name) {
System.out.println(name + "开始买咖啡");
System.out.println(name + "正在买咖啡");
System.out.println(name + "买完了");
}
public static void main(String[] args) {
th th1 = new th("张三");
th th2 = new th("李四");
th th3 = new th("王五");
th1.start();
th2.start();
th3.start();
}
}
class th extends Thread {
String name;
public th(String name) {
this.name = name;
}
@Override
public void run() {
LThreadOne.buyCoffee(name);
}
}

3.实现Callable接口
package multithreading;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class LCallable {
public static void buyCoffee(String name) {
System.out.println(name + "开始买咖啡");
System.out.println(name + "正在买咖啡");
System.out.println(name + "买完了");
}
public static void main(String[] args) {
lca l1 = new lca("张三");
lca l2 = new lca("李四");
lca l3 = new lca("王五");
FutureTask futureTask1 = new FutureTask<>(l1);
FutureTask futureTask2 = new FutureTask<>(l2);
FutureTask futureTask3 = new FutureTask<>(l3);
Thread thread1 = new Thread(futureTask1);
Thread thread2 = new Thread(futureTask2);
Thread thread3 = new Thread(futureTask3);
thread1.start();
thread2.start();
thread3.start();
}
}
class lca implements Callable {
String name;
public lca(String name) {
this.name = name;
}
@Override
public String call() throws Exception {
LCallable.buyCoffee(name);
return null;
}
}

以上就是java中三种实现多线程的方式。但是观察以上结果我们也不难发现一个问题,一个窗口售卖咖啡,应该是一个人买完了另一个人才能开始买。还好这里仅仅是售卖咖啡,如果是银行的存取款,就可能会出现一笔存款被取多次的问题,这就是线程的安全问题。
线程安全问题:当多个线程操作同一个数据时,可能会出现数据的异常。
具体解决线程安全问题就需要用到同步和互斥的概念了。
互斥:一个共享资源,A访问时,其它的都被阻塞(不能访问),当A访问完成时另一个才能访问;
同步:A的结果是B的前提,也就是A、B不能同时运行。
互斥是一种特殊的同步,而同步是更为复杂的互斥。
(本文仅作个人学习记录用,如有纰漏敬请指正)
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o