From c375b3274f394db802bf3de1a729aed7ee172107 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 28 Sep 2021 01:15:35 +0300 Subject: [PATCH 1/9] add needs class and interface --- Lazyy/Lazyy.Test/Lazyy.Test.csproj | 16 +++++++++++++++ Lazyy/Lazyy.Test/UnitTest1.cs | 18 ++++++++++++++++ Lazyy/Lazyy.sln | 22 ++++++++++++++++++++ Lazyy/Lazyy/ILazy.cs | 7 +++++++ Lazyy/Lazyy/LazyFactory.cs | 13 ++++++++++++ Lazyy/Lazyy/LazyMulti.cs | 33 ++++++++++++++++++++++++++++++ Lazyy/Lazyy/LazySingle.cs | 30 +++++++++++++++++++++++++++ Lazyy/Lazyy/Lazyy.csproj | 9 ++++++++ Lazyy/Lazyy/Program.cs | 12 +++++++++++ 9 files changed, 160 insertions(+) create mode 100644 Lazyy/Lazyy.Test/Lazyy.Test.csproj create mode 100644 Lazyy/Lazyy.Test/UnitTest1.cs create mode 100644 Lazyy/Lazyy.sln create mode 100644 Lazyy/Lazyy/ILazy.cs create mode 100644 Lazyy/Lazyy/LazyFactory.cs create mode 100644 Lazyy/Lazyy/LazyMulti.cs create mode 100644 Lazyy/Lazyy/LazySingle.cs create mode 100644 Lazyy/Lazyy/Lazyy.csproj create mode 100644 Lazyy/Lazyy/Program.cs diff --git a/Lazyy/Lazyy.Test/Lazyy.Test.csproj b/Lazyy/Lazyy.Test/Lazyy.Test.csproj new file mode 100644 index 0000000..79ed337 --- /dev/null +++ b/Lazyy/Lazyy.Test/Lazyy.Test.csproj @@ -0,0 +1,16 @@ + + + + net5.0 + + false + + + + + + + + + + diff --git a/Lazyy/Lazyy.Test/UnitTest1.cs b/Lazyy/Lazyy.Test/UnitTest1.cs new file mode 100644 index 0000000..01278f3 --- /dev/null +++ b/Lazyy/Lazyy.Test/UnitTest1.cs @@ -0,0 +1,18 @@ +using NUnit.Framework; + +namespace Lazyy.Test +{ + public class Tests + { + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } + } +} \ No newline at end of file diff --git a/Lazyy/Lazyy.sln b/Lazyy/Lazyy.sln new file mode 100644 index 0000000..9e846bc --- /dev/null +++ b/Lazyy/Lazyy.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lazyy", "Lazyy\Lazyy.csproj", "{DB81654E-7FB5-4DF1-BEB0-8E701E1A3A6A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lazyy.Test", "Lazyy.Test\Lazyy.Test.csproj", "{96805220-7A8C-4502-9503-91EB73541008}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DB81654E-7FB5-4DF1-BEB0-8E701E1A3A6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DB81654E-7FB5-4DF1-BEB0-8E701E1A3A6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DB81654E-7FB5-4DF1-BEB0-8E701E1A3A6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DB81654E-7FB5-4DF1-BEB0-8E701E1A3A6A}.Release|Any CPU.Build.0 = Release|Any CPU + {96805220-7A8C-4502-9503-91EB73541008}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96805220-7A8C-4502-9503-91EB73541008}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96805220-7A8C-4502-9503-91EB73541008}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96805220-7A8C-4502-9503-91EB73541008}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Lazyy/Lazyy/ILazy.cs b/Lazyy/Lazyy/ILazy.cs new file mode 100644 index 0000000..36400b1 --- /dev/null +++ b/Lazyy/Lazyy/ILazy.cs @@ -0,0 +1,7 @@ +namespace Lazyy +{ + public interface ILazy + { + public T Get(); + } +} \ No newline at end of file diff --git a/Lazyy/Lazyy/LazyFactory.cs b/Lazyy/Lazyy/LazyFactory.cs new file mode 100644 index 0000000..231eaa4 --- /dev/null +++ b/Lazyy/Lazyy/LazyFactory.cs @@ -0,0 +1,13 @@ +using System; + +namespace Lazyy +{ + public class LazyFactory + { + public static LazySingle CreateSingleLazy(Func supplier) + => new LazySingle(supplier); + + public static LazyMulti CreateMultiLazy(Func supplier) + => new LazyMulti(supplier); + } +} \ No newline at end of file diff --git a/Lazyy/Lazyy/LazyMulti.cs b/Lazyy/Lazyy/LazyMulti.cs new file mode 100644 index 0000000..3bfe6e2 --- /dev/null +++ b/Lazyy/Lazyy/LazyMulti.cs @@ -0,0 +1,33 @@ +using System; + +namespace Lazyy +{ + public class LazyMulti : ILazy + { + private T Value; + private bool IsGenerate = false; + private Func Supplier; + private Object lockObject = new Object(); + + public LazyMulti(Func supplierNew) + { + Supplier = supplierNew ?? throw new NullReferenceException(); + } + + public T Get() + { + if (IsGenerate) + { + return Value; + } + + lock (this.lockObject) + { + IsGenerate = true; + Value = Supplier(); + Supplier = null; + return Value; + } + } + } +} \ No newline at end of file diff --git a/Lazyy/Lazyy/LazySingle.cs b/Lazyy/Lazyy/LazySingle.cs new file mode 100644 index 0000000..ce1d01f --- /dev/null +++ b/Lazyy/Lazyy/LazySingle.cs @@ -0,0 +1,30 @@ +using System; + +namespace Lazyy +{ + public class LazySingle : ILazy + { + private T Value; + private Func Supplier; + private bool IsGenerate = false; + + + public LazySingle(Func supplierNew) + { + Supplier = supplierNew ?? throw new NullReferenceException(); + } + + public T Get() + { + if (IsGenerate) + { + return Value; + } + + IsGenerate = true; + Value = Supplier(); + Supplier = null; + return Value; + } + } +} \ No newline at end of file diff --git a/Lazyy/Lazyy/Lazyy.csproj b/Lazyy/Lazyy/Lazyy.csproj new file mode 100644 index 0000000..a184b89 --- /dev/null +++ b/Lazyy/Lazyy/Lazyy.csproj @@ -0,0 +1,9 @@ + + + + Exe + net5.0 + Windows + + + diff --git a/Lazyy/Lazyy/Program.cs b/Lazyy/Lazyy/Program.cs new file mode 100644 index 0000000..8287346 --- /dev/null +++ b/Lazyy/Lazyy/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace Lazyy +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} \ No newline at end of file From cae4051af483cd93d50b1d493af432192a956790 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 28 Sep 2021 11:58:06 +0300 Subject: [PATCH 2/9] add some tests --- Lazyy/Lazyy.Test/Lazyy.Test.csproj | 12 +++++--- Lazyy/Lazyy.Test/MultiThreadTest.cs | 42 ++++++++++++++++++++++++++++ Lazyy/Lazyy.Test/SingleThreadTest.cs | 29 +++++++++++++++++++ Lazyy/Lazyy.Test/UnitTest1.cs | 18 ------------ Lazyy/Lazyy/LazyFactory.cs | 2 +- Lazyy/Lazyy/LazyMulti.cs | 24 ++++++++-------- Lazyy/Lazyy/LazySingle.cs | 20 ++++++------- Lazyy/Lazyy/Program.cs | 38 ++++++++++++++++++++++++- 8 files changed, 139 insertions(+), 46 deletions(-) create mode 100644 Lazyy/Lazyy.Test/MultiThreadTest.cs create mode 100644 Lazyy/Lazyy.Test/SingleThreadTest.cs delete mode 100644 Lazyy/Lazyy.Test/UnitTest1.cs diff --git a/Lazyy/Lazyy.Test/Lazyy.Test.csproj b/Lazyy/Lazyy.Test/Lazyy.Test.csproj index 79ed337..5186ebf 100644 --- a/Lazyy/Lazyy.Test/Lazyy.Test.csproj +++ b/Lazyy/Lazyy.Test/Lazyy.Test.csproj @@ -7,10 +7,14 @@ - - - - + + + + + + + + diff --git a/Lazyy/Lazyy.Test/MultiThreadTest.cs b/Lazyy/Lazyy.Test/MultiThreadTest.cs new file mode 100644 index 0000000..6981102 --- /dev/null +++ b/Lazyy/Lazyy.Test/MultiThreadTest.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading; +using NUnit.Framework; + +namespace Lazyy.Test +{ + public class MultiThreadTest + { + [Test] + public void NormalWorkForMultiTest() + { + var number = 2; + var lazyMulti = LazyFactory.CreateMultiLazy(() => + { + number *= number; + return number; + }); + + var threads = new Thread[10]; + for (int i = 0; i < threads.Length; i++) + { + threads[i] = new Thread(() => lazyMulti.Get()); + } + + foreach (var thread in threads) + { + thread.Start(); + } + foreach (var thread in threads) + { + thread.Join(); + } + Assert.AreEqual(4, lazyMulti.Get()); + } + + [Test] + public void NullExceptionTest() + { + Assert.Throws(() => LazyFactory.CreateMultiLazy(null)); + } + } +} \ No newline at end of file diff --git a/Lazyy/Lazyy.Test/SingleThreadTest.cs b/Lazyy/Lazyy.Test/SingleThreadTest.cs new file mode 100644 index 0000000..64bb521 --- /dev/null +++ b/Lazyy/Lazyy.Test/SingleThreadTest.cs @@ -0,0 +1,29 @@ +using System; +using NUnit.Framework; + +namespace Lazyy.Test +{ + public class SingleThreadTest + { + [Test] + public void NormalWorkForSingleTest() + { + var number = 2; + var lazySingle = LazyFactory.CreateSingleLazy(() => + { + number += number; + return number; + }); + for (int i = 0; i < 100; i++) + { + Assert.AreEqual(4, lazySingle.Get()); + } + } + + [Test] + public void NullExceptionTest() + { + Assert.Throws(() => LazyFactory.CreateSingleLazy(null)); + } + } +} \ No newline at end of file diff --git a/Lazyy/Lazyy.Test/UnitTest1.cs b/Lazyy/Lazyy.Test/UnitTest1.cs deleted file mode 100644 index 01278f3..0000000 --- a/Lazyy/Lazyy.Test/UnitTest1.cs +++ /dev/null @@ -1,18 +0,0 @@ -using NUnit.Framework; - -namespace Lazyy.Test -{ - public class Tests - { - [SetUp] - public void Setup() - { - } - - [Test] - public void Test1() - { - Assert.Pass(); - } - } -} \ No newline at end of file diff --git a/Lazyy/Lazyy/LazyFactory.cs b/Lazyy/Lazyy/LazyFactory.cs index 231eaa4..9518462 100644 --- a/Lazyy/Lazyy/LazyFactory.cs +++ b/Lazyy/Lazyy/LazyFactory.cs @@ -10,4 +10,4 @@ public static LazySingle CreateSingleLazy(Func supplier) public static LazyMulti CreateMultiLazy(Func supplier) => new LazyMulti(supplier); } -} \ No newline at end of file +} diff --git a/Lazyy/Lazyy/LazyMulti.cs b/Lazyy/Lazyy/LazyMulti.cs index 3bfe6e2..ad10bb8 100644 --- a/Lazyy/Lazyy/LazyMulti.cs +++ b/Lazyy/Lazyy/LazyMulti.cs @@ -4,29 +4,29 @@ namespace Lazyy { public class LazyMulti : ILazy { - private T Value; - private bool IsGenerate = false; - private Func Supplier; - private Object lockObject = new Object(); + private T _value; + private bool _isGenerate = false; + private Func _supplier; + private readonly Object _lockObject = new Object(); public LazyMulti(Func supplierNew) { - Supplier = supplierNew ?? throw new NullReferenceException(); + _supplier = supplierNew ?? throw new NullReferenceException(); } public T Get() { - if (IsGenerate) + if (_isGenerate) { - return Value; + return _value; } - lock (this.lockObject) + lock (this._lockObject) { - IsGenerate = true; - Value = Supplier(); - Supplier = null; - return Value; + _isGenerate = true; + _value = _supplier(); + _supplier = null; + return _value; } } } diff --git a/Lazyy/Lazyy/LazySingle.cs b/Lazyy/Lazyy/LazySingle.cs index ce1d01f..e1cd9a0 100644 --- a/Lazyy/Lazyy/LazySingle.cs +++ b/Lazyy/Lazyy/LazySingle.cs @@ -4,27 +4,27 @@ namespace Lazyy { public class LazySingle : ILazy { - private T Value; - private Func Supplier; - private bool IsGenerate = false; + private T _value; + private Func _supplier; + private bool _isGenerate = false; public LazySingle(Func supplierNew) { - Supplier = supplierNew ?? throw new NullReferenceException(); + _supplier = supplierNew ?? throw new NullReferenceException(); } public T Get() { - if (IsGenerate) + if (_isGenerate) { - return Value; + return _value; } - IsGenerate = true; - Value = Supplier(); - Supplier = null; - return Value; + _isGenerate = true; + _value = _supplier(); + _supplier = null; + return _value; } } } \ No newline at end of file diff --git a/Lazyy/Lazyy/Program.cs b/Lazyy/Lazyy/Program.cs index 8287346..a934762 100644 --- a/Lazyy/Lazyy/Program.cs +++ b/Lazyy/Lazyy/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; namespace Lazyy { @@ -6,7 +7,42 @@ class Program { static void Main(string[] args) { - Console.WriteLine("Hello World!"); + var number1 = 2; + var number2 = 2; + var single = LazyFactory.CreateSingleLazy(() => + { + number1 += number1; + return number1; + }); + var multi = LazyFactory.CreateMultiLazy(() => + { + number2 *= number2; + return number2; + }); + + var threads = new Thread[5]; + for (int i = 0; i < threads.Length; i++) + { + threads[i] = new Thread(() => multi.Get()); + } + + foreach (var t in threads) + { + Console.WriteLine(multi.Get()); + Console.WriteLine("!!!"); + var get = single.Get(); + Console.WriteLine(get); + Console.WriteLine("!!!"); + } + foreach (var thread in threads) + { + thread.Start(); + } + foreach (var thread in threads) + { + thread.Join(); + } + } } } \ No newline at end of file From c368a97b5715e5730d84a645b9399061ec2d9110 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 28 Sep 2021 20:17:58 +0300 Subject: [PATCH 3/9] add comments --- Lazyy/Lazyy/LazyFactory.cs | 3 +++ Lazyy/Lazyy/LazyMulti.cs | 3 +++ Lazyy/Lazyy/LazySingle.cs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/Lazyy/Lazyy/LazyFactory.cs b/Lazyy/Lazyy/LazyFactory.cs index 9518462..545e689 100644 --- a/Lazyy/Lazyy/LazyFactory.cs +++ b/Lazyy/Lazyy/LazyFactory.cs @@ -2,6 +2,9 @@ namespace Lazyy { + /// + /// создает обьекты для работы либо в однопоточном, лио многопоточном режиме + /// public class LazyFactory { public static LazySingle CreateSingleLazy(Func supplier) diff --git a/Lazyy/Lazyy/LazyMulti.cs b/Lazyy/Lazyy/LazyMulti.cs index ad10bb8..6c5700e 100644 --- a/Lazyy/Lazyy/LazyMulti.cs +++ b/Lazyy/Lazyy/LazyMulti.cs @@ -2,6 +2,9 @@ namespace Lazyy { + /// + /// реаилизация многопоточного режима + /// public class LazyMulti : ILazy { private T _value; diff --git a/Lazyy/Lazyy/LazySingle.cs b/Lazyy/Lazyy/LazySingle.cs index e1cd9a0..f13fa51 100644 --- a/Lazyy/Lazyy/LazySingle.cs +++ b/Lazyy/Lazyy/LazySingle.cs @@ -2,6 +2,9 @@ namespace Lazyy { + /// + /// реаилизация однопоточного режима + /// public class LazySingle : ILazy { private T _value; From ea0fe95a058ab742df6bb4e8e38000703d9b9723 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Fri, 1 Oct 2021 00:08:22 +0300 Subject: [PATCH 4/9] fix code --- Lazyy/Lazyy.Test/MultiThreadTest.cs | 8 ++++---- Lazyy/Lazyy.Test/SingleThreadTest.cs | 4 ++-- Lazyy/Lazyy/ILazy.cs | 8 +++++++- Lazyy/Lazyy/LazyFactory.cs | 12 +++++++++--- Lazyy/Lazyy/LazyMulti.cs | 23 +++++++++++++++-------- Lazyy/Lazyy/LazySingle.cs | 15 +++++++++------ Lazyy/Lazyy/Program.cs | 12 +++++------- 7 files changed, 51 insertions(+), 31 deletions(-) diff --git a/Lazyy/Lazyy.Test/MultiThreadTest.cs b/Lazyy/Lazyy.Test/MultiThreadTest.cs index 6981102..12e4d7c 100644 --- a/Lazyy/Lazyy.Test/MultiThreadTest.cs +++ b/Lazyy/Lazyy.Test/MultiThreadTest.cs @@ -10,7 +10,7 @@ public class MultiThreadTest public void NormalWorkForMultiTest() { var number = 2; - var lazyMulti = LazyFactory.CreateMultiLazy(() => + var lazyMulti = LazyFactory.CreateMultiLazy(() => { number *= number; return number; @@ -22,11 +22,11 @@ public void NormalWorkForMultiTest() threads[i] = new Thread(() => lazyMulti.Get()); } - foreach (var thread in threads) + foreach (var thread in threads) { thread.Start(); } - foreach (var thread in threads) + foreach (var thread in threads) { thread.Join(); } @@ -36,7 +36,7 @@ public void NormalWorkForMultiTest() [Test] public void NullExceptionTest() { - Assert.Throws(() => LazyFactory.CreateMultiLazy(null)); + Assert.Throws(() => LazyFactory.CreateMultiLazy(null)); } } } \ No newline at end of file diff --git a/Lazyy/Lazyy.Test/SingleThreadTest.cs b/Lazyy/Lazyy.Test/SingleThreadTest.cs index 64bb521..ed9d028 100644 --- a/Lazyy/Lazyy.Test/SingleThreadTest.cs +++ b/Lazyy/Lazyy.Test/SingleThreadTest.cs @@ -9,7 +9,7 @@ public class SingleThreadTest public void NormalWorkForSingleTest() { var number = 2; - var lazySingle = LazyFactory.CreateSingleLazy(() => + var lazySingle = LazyFactory.CreateSingleLazy(() => { number += number; return number; @@ -23,7 +23,7 @@ public void NormalWorkForSingleTest() [Test] public void NullExceptionTest() { - Assert.Throws(() => LazyFactory.CreateSingleLazy(null)); + Assert.Throws(() => LazyFactory.CreateSingleLazy(null)); } } } \ No newline at end of file diff --git a/Lazyy/Lazyy/ILazy.cs b/Lazyy/Lazyy/ILazy.cs index 36400b1..139066e 100644 --- a/Lazyy/Lazyy/ILazy.cs +++ b/Lazyy/Lazyy/ILazy.cs @@ -1,7 +1,13 @@ namespace Lazyy { - public interface ILazy + /// + /// интерфейс ленивого вычисления + /// + public interface ILazy { + /// + /// вызывает вычисление один раз и возвращает один и тот же обьект, полученный при вычислении + /// public T Get(); } } \ No newline at end of file diff --git a/Lazyy/Lazyy/LazyFactory.cs b/Lazyy/Lazyy/LazyFactory.cs index 545e689..8112369 100644 --- a/Lazyy/Lazyy/LazyFactory.cs +++ b/Lazyy/Lazyy/LazyFactory.cs @@ -5,12 +5,18 @@ namespace Lazyy /// /// создает обьекты для работы либо в однопоточном, лио многопоточном режиме /// - public class LazyFactory + public static class LazyFactory { - public static LazySingle CreateSingleLazy(Func supplier) + /// + /// создает обьект в однопоточном режиме + /// + public static ILazy CreateSingleLazy(Func supplier) => new LazySingle(supplier); - public static LazyMulti CreateMultiLazy(Func supplier) + /// + /// создает обьект в многопоточном режиме + /// + public static ILazy CreateMultiLazy(Func supplier) => new LazyMulti(supplier); } } diff --git a/Lazyy/Lazyy/LazyMulti.cs b/Lazyy/Lazyy/LazyMulti.cs index 6c5700e..206d784 100644 --- a/Lazyy/Lazyy/LazyMulti.cs +++ b/Lazyy/Lazyy/LazyMulti.cs @@ -3,29 +3,36 @@ namespace Lazyy { /// - /// реаилизация многопоточного режима + /// реализация многопоточного режима /// public class LazyMulti : ILazy { private T _value; private bool _isGenerate = false; private Func _supplier; - private readonly Object _lockObject = new Object(); - - public LazyMulti(Func supplierNew) - { - _supplier = supplierNew ?? throw new NullReferenceException(); - } + private readonly Object _lockObject = new(); + /// + /// создает обьект в многопоточном режиме + /// + public LazyMulti(Func supplierNew) + => _supplier = supplierNew ?? throw new NullReferenceException(); + + /// + /// вызывает вычисление один раз и возвращает один и тот же обьект, полученный при вычислении + /// public T Get() { if (_isGenerate) { return _value; } - lock (this._lockObject) { + if (_isGenerate) + { + return _value; + } _isGenerate = true; _value = _supplier(); _supplier = null; diff --git a/Lazyy/Lazyy/LazySingle.cs b/Lazyy/Lazyy/LazySingle.cs index f13fa51..22d4ca2 100644 --- a/Lazyy/Lazyy/LazySingle.cs +++ b/Lazyy/Lazyy/LazySingle.cs @@ -3,7 +3,7 @@ namespace Lazyy { /// - /// реаилизация однопоточного режима + /// реализация однопоточного режима /// public class LazySingle : ILazy { @@ -11,12 +11,15 @@ public class LazySingle : ILazy private Func _supplier; private bool _isGenerate = false; - + /// + /// создает обьект в однопоточном режиме + /// public LazySingle(Func supplierNew) - { - _supplier = supplierNew ?? throw new NullReferenceException(); - } - + => _supplier = supplierNew ?? throw new NullReferenceException(); + + /// + /// вызывает вычисление один раз и возвращает один и тот же обьект, полученный при вычислении + /// public T Get() { if (_isGenerate) diff --git a/Lazyy/Lazyy/Program.cs b/Lazyy/Lazyy/Program.cs index a934762..05c0c57 100644 --- a/Lazyy/Lazyy/Program.cs +++ b/Lazyy/Lazyy/Program.cs @@ -9,12 +9,12 @@ static void Main(string[] args) { var number1 = 2; var number2 = 2; - var single = LazyFactory.CreateSingleLazy(() => + var single = LazyFactory.CreateMultiLazy(() => { number1 += number1; return number1; }); - var multi = LazyFactory.CreateMultiLazy(() => + var multi = LazyFactory.CreateMultiLazy(() => { number2 *= number2; return number2; @@ -30,19 +30,17 @@ static void Main(string[] args) { Console.WriteLine(multi.Get()); Console.WriteLine("!!!"); - var get = single.Get(); - Console.WriteLine(get); + Console.WriteLine(single.Get()); Console.WriteLine("!!!"); } - foreach (var thread in threads) + foreach (var thread in threads) { thread.Start(); } - foreach (var thread in threads) + foreach (var thread in threads) { thread.Join(); } - } } } \ No newline at end of file From 583ef8b1c165d4894de647d4d5c8e805c61a45c7 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Sun, 10 Oct 2021 19:37:02 +0300 Subject: [PATCH 5/9] fix code --- Lazyy/Lazyy.Test/MultiThreadTest.cs | 8 ++++---- Lazyy/Lazyy.Test/SingleThreadTest.cs | 4 +--- Lazyy/Lazyy/LazyFactory.cs | 4 ++-- Lazyy/Lazyy/LazyMulti.cs | 10 ++++++---- Lazyy/Lazyy/LazySingle.cs | 8 ++++---- Lazyy/Lazyy/Program.cs | 4 +++- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Lazyy/Lazyy.Test/MultiThreadTest.cs b/Lazyy/Lazyy.Test/MultiThreadTest.cs index 12e4d7c..37eeeec 100644 --- a/Lazyy/Lazyy.Test/MultiThreadTest.cs +++ b/Lazyy/Lazyy.Test/MultiThreadTest.cs @@ -15,7 +15,7 @@ public void NormalWorkForMultiTest() number *= number; return number; }); - + var threads = new Thread[10]; for (int i = 0; i < threads.Length; i++) { @@ -26,17 +26,17 @@ public void NormalWorkForMultiTest() { thread.Start(); } + foreach (var thread in threads) { thread.Join(); } + Assert.AreEqual(4, lazyMulti.Get()); } [Test] public void NullExceptionTest() - { - Assert.Throws(() => LazyFactory.CreateMultiLazy(null)); - } + => Assert.Throws(() => LazyFactory.CreateMultiLazy(null)); } } \ No newline at end of file diff --git a/Lazyy/Lazyy.Test/SingleThreadTest.cs b/Lazyy/Lazyy.Test/SingleThreadTest.cs index ed9d028..3ec4141 100644 --- a/Lazyy/Lazyy.Test/SingleThreadTest.cs +++ b/Lazyy/Lazyy.Test/SingleThreadTest.cs @@ -22,8 +22,6 @@ public void NormalWorkForSingleTest() [Test] public void NullExceptionTest() - { - Assert.Throws(() => LazyFactory.CreateSingleLazy(null)); - } + => Assert.Throws(() => LazyFactory.CreateSingleLazy(null)); } } \ No newline at end of file diff --git a/Lazyy/Lazyy/LazyFactory.cs b/Lazyy/Lazyy/LazyFactory.cs index 8112369..d4ba51d 100644 --- a/Lazyy/Lazyy/LazyFactory.cs +++ b/Lazyy/Lazyy/LazyFactory.cs @@ -3,7 +3,7 @@ namespace Lazyy { /// - /// создает обьекты для работы либо в однопоточном, лио многопоточном режиме + /// создает обьекты для работы либо в однопоточном, либо в многопоточном режиме /// public static class LazyFactory { @@ -19,4 +19,4 @@ public static ILazy CreateSingleLazy(Func supplier) public static ILazy CreateMultiLazy(Func supplier) => new LazyMulti(supplier); } -} +} \ No newline at end of file diff --git a/Lazyy/Lazyy/LazyMulti.cs b/Lazyy/Lazyy/LazyMulti.cs index 206d784..1df7400 100644 --- a/Lazyy/Lazyy/LazyMulti.cs +++ b/Lazyy/Lazyy/LazyMulti.cs @@ -11,12 +11,12 @@ public class LazyMulti : ILazy private bool _isGenerate = false; private Func _supplier; private readonly Object _lockObject = new(); - + /// /// создает обьект в многопоточном режиме /// - public LazyMulti(Func supplierNew) - => _supplier = supplierNew ?? throw new NullReferenceException(); + public LazyMulti(Func supplier) + => _supplier = supplier ?? throw new ArgumentNullException(); /// /// вызывает вычисление один раз и возвращает один и тот же обьект, полученный при вычислении @@ -27,15 +27,17 @@ public T Get() { return _value; } + lock (this._lockObject) { if (_isGenerate) { return _value; } - _isGenerate = true; + _value = _supplier(); _supplier = null; + _isGenerate = true; return _value; } } diff --git a/Lazyy/Lazyy/LazySingle.cs b/Lazyy/Lazyy/LazySingle.cs index 22d4ca2..a81816f 100644 --- a/Lazyy/Lazyy/LazySingle.cs +++ b/Lazyy/Lazyy/LazySingle.cs @@ -10,13 +10,13 @@ public class LazySingle : ILazy private T _value; private Func _supplier; private bool _isGenerate = false; - + /// /// создает обьект в однопоточном режиме /// - public LazySingle(Func supplierNew) - => _supplier = supplierNew ?? throw new NullReferenceException(); - + public LazySingle(Func supplier) + => _supplier = supplier ?? throw new ArgumentNullException(); + /// /// вызывает вычисление один раз и возвращает один и тот же обьект, полученный при вычислении /// diff --git a/Lazyy/Lazyy/Program.cs b/Lazyy/Lazyy/Program.cs index 05c0c57..c7811b5 100644 --- a/Lazyy/Lazyy/Program.cs +++ b/Lazyy/Lazyy/Program.cs @@ -19,7 +19,7 @@ static void Main(string[] args) number2 *= number2; return number2; }); - + var threads = new Thread[5]; for (int i = 0; i < threads.Length; i++) { @@ -33,10 +33,12 @@ static void Main(string[] args) Console.WriteLine(single.Get()); Console.WriteLine("!!!"); } + foreach (var thread in threads) { thread.Start(); } + foreach (var thread in threads) { thread.Join(); From 3178cf3a3ef08bdcd0742ce7a53ec4472113df33 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 22 Nov 2021 13:23:56 +0300 Subject: [PATCH 6/9] fix --- Lazyy/Lazyy/LazyMulti.cs | 11 ++++++----- Lazyy/Lazyy/LazySingle.cs | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Lazyy/Lazyy/LazyMulti.cs b/Lazyy/Lazyy/LazyMulti.cs index 1df7400..dccc0f9 100644 --- a/Lazyy/Lazyy/LazyMulti.cs +++ b/Lazyy/Lazyy/LazyMulti.cs @@ -1,14 +1,15 @@ using System; +using System.Threading; namespace Lazyy { /// - /// реализация многопоточного режима + /// реализация ILazy в многопоточном режиме /// public class LazyMulti : ILazy { private T _value; - private bool _isGenerate = false; + private bool _isGenerated = false; private Func _supplier; private readonly Object _lockObject = new(); @@ -23,21 +24,21 @@ public LazyMulti(Func supplier) /// public T Get() { - if (_isGenerate) + if (_isGenerated) { return _value; } lock (this._lockObject) { - if (_isGenerate) + if (Volatile.Read(ref _isGenerated)) { return _value; } _value = _supplier(); + Volatile.Write(ref _isGenerated, true); _supplier = null; - _isGenerate = true; return _value; } } diff --git a/Lazyy/Lazyy/LazySingle.cs b/Lazyy/Lazyy/LazySingle.cs index a81816f..43413d9 100644 --- a/Lazyy/Lazyy/LazySingle.cs +++ b/Lazyy/Lazyy/LazySingle.cs @@ -3,13 +3,13 @@ namespace Lazyy { /// - /// реализация однопоточного режима + /// реализация ILazy в однопоточном режиме /// public class LazySingle : ILazy { private T _value; private Func _supplier; - private bool _isGenerate = false; + private bool _isGenerated = false; /// /// создает обьект в однопоточном режиме @@ -22,12 +22,12 @@ public LazySingle(Func supplier) /// public T Get() { - if (_isGenerate) + if (_isGenerated) { return _value; } - _isGenerate = true; + _isGenerated = true; _value = _supplier(); _supplier = null; return _value; From daed898942f6f53b92531c2a96170d6128737f32 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Sun, 28 Nov 2021 12:28:55 +0300 Subject: [PATCH 7/9] fix --- Lazyy/Lazyy/LazyMulti.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lazyy/Lazyy/LazyMulti.cs b/Lazyy/Lazyy/LazyMulti.cs index dccc0f9..ea058f4 100644 --- a/Lazyy/Lazyy/LazyMulti.cs +++ b/Lazyy/Lazyy/LazyMulti.cs @@ -29,7 +29,7 @@ public T Get() return _value; } - lock (this._lockObject) + lock (_lockObject) { if (Volatile.Read(ref _isGenerated)) { From 1fe5b980d0a07c39e4d2bb752613fc205a8e6b70 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Mon, 6 Dec 2021 16:19:21 +0300 Subject: [PATCH 8/9] fix test --- Lazyy/Lazyy.Test/MultiThreadTest.cs | 42 ------------------- Lazyy/Lazyy.Test/SingleThreadTest.cs | 62 +++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 52 deletions(-) delete mode 100644 Lazyy/Lazyy.Test/MultiThreadTest.cs diff --git a/Lazyy/Lazyy.Test/MultiThreadTest.cs b/Lazyy/Lazyy.Test/MultiThreadTest.cs deleted file mode 100644 index 37eeeec..0000000 --- a/Lazyy/Lazyy.Test/MultiThreadTest.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Threading; -using NUnit.Framework; - -namespace Lazyy.Test -{ - public class MultiThreadTest - { - [Test] - public void NormalWorkForMultiTest() - { - var number = 2; - var lazyMulti = LazyFactory.CreateMultiLazy(() => - { - number *= number; - return number; - }); - - var threads = new Thread[10]; - for (int i = 0; i < threads.Length; i++) - { - threads[i] = new Thread(() => lazyMulti.Get()); - } - - foreach (var thread in threads) - { - thread.Start(); - } - - foreach (var thread in threads) - { - thread.Join(); - } - - Assert.AreEqual(4, lazyMulti.Get()); - } - - [Test] - public void NullExceptionTest() - => Assert.Throws(() => LazyFactory.CreateMultiLazy(null)); - } -} \ No newline at end of file diff --git a/Lazyy/Lazyy.Test/SingleThreadTest.cs b/Lazyy/Lazyy.Test/SingleThreadTest.cs index 3ec4141..2f3044b 100644 --- a/Lazyy/Lazyy.Test/SingleThreadTest.cs +++ b/Lazyy/Lazyy.Test/SingleThreadTest.cs @@ -1,27 +1,69 @@ using System; +using System.Collections.Generic; +using System.Threading; using NUnit.Framework; namespace Lazyy.Test { public class SingleThreadTest { + private static IEnumerable Lazy() + { + int countForSingle = 0; + int countForMulti = 0; + yield return new TestCaseData(LazyFactory.CreateSingleLazy(() => ++countForSingle)); + yield return new TestCaseData(LazyFactory.CreateMultiLazy(() => Interlocked.Increment(ref countForMulti))); + } + [Test] - public void NormalWorkForSingleTest() + public void SupplierCannotBeNull() + { + Assert.Throws(() => LazyFactory.CreateSingleLazy(null)); + Assert.Throws(() => LazyFactory.CreateMultiLazy(null)); + } + + [TestCaseSource(nameof(Lazy))] + public void TestLazyLaunchFunctionOnly1Time(ILazy lazy) { - var number = 2; - var lazySingle = LazyFactory.CreateSingleLazy(() => - { - number += number; - return number; - }); for (int i = 0; i < 100; i++) { - Assert.AreEqual(4, lazySingle.Get()); + Assert.AreEqual(1, lazy.Get()); + } + } + + [TestCaseSource(nameof(Lazy))] + public void GetShouldNotChangeValue(ILazy lazy) + { + var value = lazy.Get(); + Assert.AreEqual(1, value); + for (int i = 0; i < 25; i++) + { + Assert.AreEqual(value, lazy.Get()); } } [Test] - public void NullExceptionTest() - => Assert.Throws(() => LazyFactory.CreateSingleLazy(null)); + public void RaceConditionsCheck() + { + var count = 0; + var lazy = LazyFactory.CreateMultiLazy(() => Interlocked.Increment(ref count)); + var threads = new Thread[10]; + + for (int i = 0; i < threads.Length; ++i) + { + threads[i] = new Thread(() => lazy.Get()); + } + + foreach (var thread in threads) + { + thread.Start(); + } + foreach (var thread in threads) + { + thread.Join(); + } + + Assert.AreEqual(1, count); + } } } \ No newline at end of file From a83301117fcfac1e2bcb3598f6acac94e7547ba5 Mon Sep 17 00:00:00 2001 From: MikePuzanov Date: Tue, 7 Dec 2021 22:07:59 +0300 Subject: [PATCH 9/9] rename file --- Lazyy/Lazyy.Test/{SingleThreadTest.cs => LazyTest.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Lazyy/Lazyy.Test/{SingleThreadTest.cs => LazyTest.cs} (100%) diff --git a/Lazyy/Lazyy.Test/SingleThreadTest.cs b/Lazyy/Lazyy.Test/LazyTest.cs similarity index 100% rename from Lazyy/Lazyy.Test/SingleThreadTest.cs rename to Lazyy/Lazyy.Test/LazyTest.cs